{
    "file_diffs": [
        {
            "old_file_content": "2.0b0 (2020-12-15)\n==================\n\n- Overhaul tutorials and update cookiecutter to de-emphasize ``request.user``\n  in favor of ``request.identity`` for common use cases.\n  See https://github.com/Pylons/pyramid/pull/3629\n\n- Improve documentation and patterns with builtin fixtures shipped in the\n  cookiecutters.\n  See https://github.com/Pylons/pyramid/pull/3629\n\n2.0a0 (2020-11-29)\n==================\n\nFeatures\n--------\n\n- Add support for Python 3.9.\n  See https://github.com/Pylons/pyramid/issues/3622\n\n- The ``aslist`` method now handles non-string objects when flattening.\n  See https://github.com/Pylons/pyramid/pull/3594\n\n- It is now possible to pass multiple values to the ``header`` predicate\n  for route and view configuration.\n  See https://github.com/Pylons/pyramid/pull/3576\n\n- Add support for Python 3.8.\n  See https://github.com/Pylons/pyramid/pull/3547\n\n- New security APIs have been added to support a massive overhaul of the\n  authentication and authorization system. Read\n  \"Upgrading Authentication/Authorization\" in the \"What's New in Pyramid 2.0\"\n  chapter of the documentation for information about using this new system.\n\n  - ``pyramid.config.Configurator.set_security_policy``.\n  - ``pyramid.interfaces.ISecurityPolicy``\n  - ``pyramid.request.Request.identity``.\n  - ``pyramid.request.Request.is_authenticated``\n  - ``pyramid.authentication.SessionAuthenticationHelper``\n  - ``pyramid.authorization.ACLHelper``\n  - ``is_authenticated=True/False`` predicate for route and view configs\n\n  See https://github.com/Pylons/pyramid/pull/3465 and\n  https://github.com/Pylons/pyramid/pull/3598\n\n- Changed the default ``serializer`` on\n  ``pyramid.session.SignedCookieSessionFactory`` to use\n  ``pyramid.session.JSONSerializer`` instead of\n  ``pyramid.session.PickleSerializer``. Read\n  \"Upgrading Session Serialization\" in the \"What's New in Pyramid 2.0\" chapter\n  of the documentation for more information about why this change was made.\n  See https://github.com/Pylons/pyramid/pull/3413\n\n- It is now possible to control whether a route pattern contains a trailing\n  slash when it is composed with a route prefix using\n  ``config.include(..., route_prefix=...)`` or\n  ``with config.route_prefix_context(...)``. This can be done by specifying\n  an empty pattern and setting the new argument\n  ``inherit_slash=True``. For example:\n\n  .. code-block:: python\n\n      with config.route_prefix_context('/users'):\n          config.add_route('users', '', inherit_slash=True)\n\n  In the example, the resulting pattern will be ``/users``. Similarly, if the\n  route prefix were ``/users/`` then the final pattern would be ``/users/``.\n  If the ``pattern`` was ``'/'``, then the final pattern would always be\n  ``/users/``. This new setting is only available if the pattern supplied\n  to ``add_route`` is the empty string (``''``).\n  See https://github.com/Pylons/pyramid/pull/3420\n\n- No longer define ``pyramid.request.Request.json_body`` which is already\n  provided by WebOb. This allows the attribute to now be settable.\n  See https://github.com/Pylons/pyramid/pull/3447\n\n- Improve debugging info from ``pyramid.view.view_config`` decorator.\n  See https://github.com/Pylons/pyramid/pull/3483\n\n- A new parameter, ``allow_no_origin``, was added to\n  ``pyramid.config.Configurator.set_default_csrf_options`` as well as\n  ``pyramid.csrf.check_csrf_origin``. This option controls whether a\n  request is rejected if it has no ``Origin`` or ``Referer`` header -\n  often the result of a user configuring their browser not to send a\n  ``Referer`` header for privacy reasons even on same-domain requests.\n  The default is to reject requests without a known origin. It is also\n  possible to allow the special ``Origin: null`` header by adding it to the\n  ``pyramid.csrf_trusted_origins`` list in the settings.\n  See https://github.com/Pylons/pyramid/pull/3512\n  and https://github.com/Pylons/pyramid/pull/3518\n\n- A new parameter, ``check_origin``, was added to\n  ``pyramid.config.Configurator.set_default_csrf_options`` which disables\n  origin checking entirely.\n  See https://github.com/Pylons/pyramid/pull/3518\n\n- Added ``pyramid.interfaces.IPredicateInfo`` which defines the object passed\n  to predicate factories as their second argument.\n  See https://github.com/Pylons/pyramid/pull/3514\n\n- Added support for serving pre-compressed static assets by using the\n  ``content_encodings`` argument of\n  ``pyramid.config.Configurator.add_static_view`` and\n  ``pyramid.static.static_view``.\n  See https://github.com/Pylons/pyramid/pull/3537\n\n- Fix ``DeprecationWarning`` emitted by using the ``imp`` module.\n  See https://github.com/Pylons/pyramid/pull/3553\n\n- Properties created via ``config.add_request_method(..., property=True)`` or\n  ``request.set_property`` used to be readonly. They can now be overridden\n  via ``request.foo = ...`` and until the value is deleted it will return\n  the overridden value. This is most useful when mocking request properties\n  in testing.\n  See https://github.com/Pylons/pyramid/pull/3559\n\n- Finished callbacks are now executed as part of the ``closer`` that is\n  invoked as part of ``pyramid.scripting.prepare`` and\n  ``pyramid.paster.bootstrap``.\n  See https://github.com/Pylons/pyramid/pull/3561\n\n- Added ``pyramid.request.RequestLocalCache`` which can be used to create\n  simple objects that are shared across requests and can be used to store\n  per-request data. This is useful when the source of data is external to\n  the request itself. Often a reified property is used on a request via\n  ``pyramid.config.Configurator.add_request_method``, or\n  ``pyramid.decorator.reify``, and these work great when the data is\n  generated on-demand when accessing the request property. However, often\n  the case is that the data is generated when accessing some other system\n  and then we want to cache the data for the duration of the request.\n  See https://github.com/Pylons/pyramid/pull/3561\n\n- Exposed ``pyramid.authorization.ALL_PERMISSIONS`` and\n  ``pyramid.authorization.DENY_ALL`` such that all of the ACL-related constants\n  are now importable from the ``pyramid.authorization`` namespace.\n  See https://github.com/Pylons/pyramid/pull/3563\n\n- ``pserve`` now outputs verbose messaging to `stderr` instead of `stdout`\n  to circumvent buffering issues that exist by default on `stdout`.\n  See https://github.com/Pylons/pyramid/pull/3593\n\nDeprecations\n------------\n\n- Deprecated the authentication and authorization interfaces and\n  principal-based support. See \"Upgrading Authentication/Authorization\" in\n  the \"What's New in Pyramid 2.0\" chapter of the documentation for information\n  on equivalent APIs and notes on upgrading. The following APIs are deprecated\n  as a result of this change:\n\n  - ``pyramid.config.Configurator.set_authentication_policy``\n  - ``pyramid.config.Configurator.set_authorization_policy``\n  - ``pyramid.interfaces.IAuthenticationPolicy``\n  - ``pyramid.interfaces.IAuthorizationPolicy``\n  - ``pyramid.request.Request.effective_principals``\n  - ``pyramid.request.Request.unauthenticated_userid``\n  - ``pyramid.authentication.AuthTktAuthenticationPolicy``\n  - ``pyramid.authentication.RemoteUserAuthenticationPolicy``\n  - ``pyramid.authentication.RepozeWho1AuthenticationPolicy``\n  - ``pyramid.authentication.SessionAuthenticationPolicy``\n  - ``pyramid.authentication.BasicAuthAuthenticationPolicy``\n  - ``pyramid.authorization.ACLAuthorizationPolicy``\n  - The ``effective_principals`` view and route predicates.\n\n  See https://github.com/Pylons/pyramid/pull/3465\n\n- Deprecated ``pyramid.security.principals_allowed_by_permission``. This\n  method continues to work with the deprecated\n  ``pyramid.interfaces.IAuthorizationPolicy`` interface but will not work with\n  the new ``pyramid.interfaces.ISecurityPolicy``.\n  See https://github.com/Pylons/pyramid/pull/3465\n\n- Deprecated several ACL-related aspects of ``pyramid.security``. Equivalent\n  objects should now be imported from the ``pyramid.authorization`` namespace.\n  This includes:\n\n  - ``pyramid.security.Everyone``\n  - ``pyramid.security.Authenticated``\n  - ``pyramid.security.ALL_PERMISSIONS``\n  - ``pyramid.security.DENY_ALL``\n  - ``pyramid.security.ACLAllowed``\n  - ``pyramid.security.ACLDenied``\n\n  See https://github.com/Pylons/pyramid/pull/3563\n\n- Deprecated ``pyramid.session.PickleSerializer``.\n  See https://github.com/pylons/pyramid/issues/2709,\n  and https://github.com/pylons/pyramid/pull/3353,\n  and https://github.com/pylons/pyramid/pull/3413\n\nBackward Incompatibilities\n--------------------------\n\n- Drop support for Python 2.7, 3.4, and 3.5.\n  See https://github.com/Pylons/pyramid/pull/3421,\n  and https://github.com/Pylons/pyramid/pull/3547,\n  and https://github.com/Pylons/pyramid/pull/3634\n\n- Removed the ``pyramid.compat`` module. Integrators should use the ``six``\n  module or vendor shims they are using into their own codebases going forward.\n  https://github.com/Pylons/pyramid/pull/3421\n\n- ``pcreate`` and the builtin scaffolds have been removed in favor of\n  using the ``cookiecutter`` tool and the ``pyramid-cookiecutter-starter``\n  cookiecutter. The script and scaffolds were deprecated in Pyramid 1.8.\n  See https://github.com/Pylons/pyramid/pull/3406\n\n- Changed the default ``hashalg`` on\n  ``pyramid.authentication.AuthTktCookieHelper`` to ``sha512``.\n  See https://github.com/Pylons/pyramid/pull/3557\n\n- Removed ``pyramid.interfaces.ITemplateRenderer``. This interface was\n  deprecated since Pyramid 1.5 and was an interface\n  used by libraries like ``pyramid_mako`` and ``pyramid_chameleon`` but\n  provided no functionality within Pyramid itself.\n  See https://github.com/Pylons/pyramid/pull/3409\n\n- Removed ``pyramid.security.has_permission``,\n  ``pyramid.security.authenticated_userid``,\n  ``pyramid.security.unauthenticated_userid``, and\n  ``pyramid.security.effective_principals``. These methods were deprecated\n  in Pyramid 1.5 and all have equivalents available as properties on the\n  request. For example, ``request.authenticated_userid``.\n  See https://github.com/Pylons/pyramid/pull/3410\n\n- Removed support for supplying a media range to the ``accept`` predicate of\n  both ``pyramid.config.Configurator.add_view`` and\n  ``pyramid.config.Configurator.add_route``. These options were deprecated\n  in Pyramid 1.10 and WebOb 1.8 because they resulted in uncontrollable\n  matching that was not compliant with the RFC.\n  See https://github.com/Pylons/pyramid/pull/3411\n\n- Removed ``pyramid.session.UnencryptedCookieSessionFactoryConfig``. This\n  session factory was replaced with\n  ``pyramid.session.SignedCookieSessionFactory`` in Pyramid 1.5 and has been\n  deprecated since then.\n  See https://github.com/Pylons/pyramid/pull/3412\n\n- Removed ``pyramid.session.signed_serialize``, and\n  ``pyramid.session.signed_deserialize``. These methods were only used by\n  the now-removed ``pyramid.session.UnencryptedCookieSessionFactoryConfig``\n  and were coupled to the vulnerable pickle serialization format which could\n  lead to remove code execution if the secret key is compromised.\n  See https://github.com/Pylons/pyramid/pull/3412\n\n- Changed the default ``serializer`` on\n  ``pyramid.session.SignedCookieSessionFactory`` to use\n  ``pyramid.session.JSONSerializer`` instead of\n  ``pyramid.session.PickleSerializer``. Read \"Upgrading Session Serialization\"\n  in the \"What's New in Pyramid 2.0\" chapter of the documentation for more\n  information about why this change was made.\n  See https://github.com/Pylons/pyramid/pull/3413\n\n- ``pyramid.request.Request.invoke_exception_view`` will no longer be called\n  by the default execution policy.\n  See https://github.com/Pylons/pyramid/pull/3496\n\n- ``pyramid.config.Configurator.scan`` will no longer, by default, execute\n  Venusian decorator callbacks registered for categories other than\n  ``'pyramid'``. To find any decorator regardless of category, specify\n  ``config.scan(..., categories=None)``.\n  See https://github.com/Pylons/pyramid/pull/3510\n\n- The second argument to predicate factories has been changed from ``config``\n  to ``info``, an instance of ``pyramid.interfaces.IPredicateInfo``. This\n  limits the data available to predicates but still provides the package,\n  registry, settings and dotted-name resolver which should cover most use\n  cases and is largely backward compatible.\n  See https://github.com/Pylons/pyramid/pull/3514\n\n- Removed the ``check_csrf`` predicate. Instead, use\n  ``pyramid.config.Configurator.set_default_csrf_options`` and the\n  ``require_csrf`` view option to enable automatic CSRF checking.\n  See https://github.com/Pylons/pyramid/pull/3521\n\n- Update the default behavior of\n  ``pyramid.authenticationAuthTktAuthenticationPolicy`` and\n  ``pyramid.authentication.AuthTktCookieHelper`` to only set a single cookie\n  without a domain parameter when no other domain constraints are specified.\n  Prior to this change, ``wild_domain=False`` (the default) was effectively\n  treated the same as ``wild_domain=True``, in which a cookie was defined\n  such that browsers would use it both for the request's domain, as well as\n  any subdomain. In the new behavior, cookies will only affect the current\n  domain, and not subdomains, by default.\n  See https://github.com/Pylons/pyramid/pull/3587\n\nDocumentation Changes\n---------------------\n\n- Restore build of PDF on Read The Docs.\n  See https://github.com/Pylons/pyramid/issues/3290\n\n- Fix docs build for Sphinx 2.0.\n  See https://github.com/Pylons/pyramid/pull/3480\n\n- Significant updates to the wiki, wiki2 tutorials to demonstrate the new\n  security policy usage as well as a much more production-ready test harness.\n  See https://github.com/Pylons/pyramid/pull/3557\n",
            "new_file_content": "Unreleased\n==========\n\n- Break potential reference cycle between ``request`` and ``context``.\n  See https://github.com/Pylons/pyramid/pull/3649\n\n2.0b0 (2020-12-15)\n==================\n\n- Overhaul tutorials and update cookiecutter to de-emphasize ``request.user``\n  in favor of ``request.identity`` for common use cases.\n  See https://github.com/Pylons/pyramid/pull/3629\n\n- Improve documentation and patterns with builtin fixtures shipped in the\n  cookiecutters.\n  See https://github.com/Pylons/pyramid/pull/3629\n\n2.0a0 (2020-11-29)\n==================\n\nFeatures\n--------\n\n- Add support for Python 3.9.\n  See https://github.com/Pylons/pyramid/issues/3622\n\n- The ``aslist`` method now handles non-string objects when flattening.\n  See https://github.com/Pylons/pyramid/pull/3594\n\n- It is now possible to pass multiple values to the ``header`` predicate\n  for route and view configuration.\n  See https://github.com/Pylons/pyramid/pull/3576\n\n- Add support for Python 3.8.\n  See https://github.com/Pylons/pyramid/pull/3547\n\n- New security APIs have been added to support a massive overhaul of the\n  authentication and authorization system. Read\n  \"Upgrading Authentication/Authorization\" in the \"What's New in Pyramid 2.0\"\n  chapter of the documentation for information about using this new system.\n\n  - ``pyramid.config.Configurator.set_security_policy``.\n  - ``pyramid.interfaces.ISecurityPolicy``\n  - ``pyramid.request.Request.identity``.\n  - ``pyramid.request.Request.is_authenticated``\n  - ``pyramid.authentication.SessionAuthenticationHelper``\n  - ``pyramid.authorization.ACLHelper``\n  - ``is_authenticated=True/False`` predicate for route and view configs\n\n  See https://github.com/Pylons/pyramid/pull/3465 and\n  https://github.com/Pylons/pyramid/pull/3598\n\n- Changed the default ``serializer`` on\n  ``pyramid.session.SignedCookieSessionFactory`` to use\n  ``pyramid.session.JSONSerializer`` instead of\n  ``pyramid.session.PickleSerializer``. Read\n  \"Upgrading Session Serialization\" in the \"What's New in Pyramid 2.0\" chapter\n  of the documentation for more information about why this change was made.\n  See https://github.com/Pylons/pyramid/pull/3413\n\n- It is now possible to control whether a route pattern contains a trailing\n  slash when it is composed with a route prefix using\n  ``config.include(..., route_prefix=...)`` or\n  ``with config.route_prefix_context(...)``. This can be done by specifying\n  an empty pattern and setting the new argument\n  ``inherit_slash=True``. For example:\n\n  .. code-block:: python\n\n      with config.route_prefix_context('/users'):\n          config.add_route('users', '', inherit_slash=True)\n\n  In the example, the resulting pattern will be ``/users``. Similarly, if the\n  route prefix were ``/users/`` then the final pattern would be ``/users/``.\n  If the ``pattern`` was ``'/'``, then the final pattern would always be\n  ``/users/``. This new setting is only available if the pattern supplied\n  to ``add_route`` is the empty string (``''``).\n  See https://github.com/Pylons/pyramid/pull/3420\n\n- No longer define ``pyramid.request.Request.json_body`` which is already\n  provided by WebOb. This allows the attribute to now be settable.\n  See https://github.com/Pylons/pyramid/pull/3447\n\n- Improve debugging info from ``pyramid.view.view_config`` decorator.\n  See https://github.com/Pylons/pyramid/pull/3483\n\n- A new parameter, ``allow_no_origin``, was added to\n  ``pyramid.config.Configurator.set_default_csrf_options`` as well as\n  ``pyramid.csrf.check_csrf_origin``. This option controls whether a\n  request is rejected if it has no ``Origin`` or ``Referer`` header -\n  often the result of a user configuring their browser not to send a\n  ``Referer`` header for privacy reasons even on same-domain requests.\n  The default is to reject requests without a known origin. It is also\n  possible to allow the special ``Origin: null`` header by adding it to the\n  ``pyramid.csrf_trusted_origins`` list in the settings.\n  See https://github.com/Pylons/pyramid/pull/3512\n  and https://github.com/Pylons/pyramid/pull/3518\n\n- A new parameter, ``check_origin``, was added to\n  ``pyramid.config.Configurator.set_default_csrf_options`` which disables\n  origin checking entirely.\n  See https://github.com/Pylons/pyramid/pull/3518\n\n- Added ``pyramid.interfaces.IPredicateInfo`` which defines the object passed\n  to predicate factories as their second argument.\n  See https://github.com/Pylons/pyramid/pull/3514\n\n- Added support for serving pre-compressed static assets by using the\n  ``content_encodings`` argument of\n  ``pyramid.config.Configurator.add_static_view`` and\n  ``pyramid.static.static_view``.\n  See https://github.com/Pylons/pyramid/pull/3537\n\n- Fix ``DeprecationWarning`` emitted by using the ``imp`` module.\n  See https://github.com/Pylons/pyramid/pull/3553\n\n- Properties created via ``config.add_request_method(..., property=True)`` or\n  ``request.set_property`` used to be readonly. They can now be overridden\n  via ``request.foo = ...`` and until the value is deleted it will return\n  the overridden value. This is most useful when mocking request properties\n  in testing.\n  See https://github.com/Pylons/pyramid/pull/3559\n\n- Finished callbacks are now executed as part of the ``closer`` that is\n  invoked as part of ``pyramid.scripting.prepare`` and\n  ``pyramid.paster.bootstrap``.\n  See https://github.com/Pylons/pyramid/pull/3561\n\n- Added ``pyramid.request.RequestLocalCache`` which can be used to create\n  simple objects that are shared across requests and can be used to store\n  per-request data. This is useful when the source of data is external to\n  the request itself. Often a reified property is used on a request via\n  ``pyramid.config.Configurator.add_request_method``, or\n  ``pyramid.decorator.reify``, and these work great when the data is\n  generated on-demand when accessing the request property. However, often\n  the case is that the data is generated when accessing some other system\n  and then we want to cache the data for the duration of the request.\n  See https://github.com/Pylons/pyramid/pull/3561\n\n- Exposed ``pyramid.authorization.ALL_PERMISSIONS`` and\n  ``pyramid.authorization.DENY_ALL`` such that all of the ACL-related constants\n  are now importable from the ``pyramid.authorization`` namespace.\n  See https://github.com/Pylons/pyramid/pull/3563\n\n- ``pserve`` now outputs verbose messaging to `stderr` instead of `stdout`\n  to circumvent buffering issues that exist by default on `stdout`.\n  See https://github.com/Pylons/pyramid/pull/3593\n\nDeprecations\n------------\n\n- Deprecated the authentication and authorization interfaces and\n  principal-based support. See \"Upgrading Authentication/Authorization\" in\n  the \"What's New in Pyramid 2.0\" chapter of the documentation for information\n  on equivalent APIs and notes on upgrading. The following APIs are deprecated\n  as a result of this change:\n\n  - ``pyramid.config.Configurator.set_authentication_policy``\n  - ``pyramid.config.Configurator.set_authorization_policy``\n  - ``pyramid.interfaces.IAuthenticationPolicy``\n  - ``pyramid.interfaces.IAuthorizationPolicy``\n  - ``pyramid.request.Request.effective_principals``\n  - ``pyramid.request.Request.unauthenticated_userid``\n  - ``pyramid.authentication.AuthTktAuthenticationPolicy``\n  - ``pyramid.authentication.RemoteUserAuthenticationPolicy``\n  - ``pyramid.authentication.RepozeWho1AuthenticationPolicy``\n  - ``pyramid.authentication.SessionAuthenticationPolicy``\n  - ``pyramid.authentication.BasicAuthAuthenticationPolicy``\n  - ``pyramid.authorization.ACLAuthorizationPolicy``\n  - The ``effective_principals`` view and route predicates.\n\n  See https://github.com/Pylons/pyramid/pull/3465\n\n- Deprecated ``pyramid.security.principals_allowed_by_permission``. This\n  method continues to work with the deprecated\n  ``pyramid.interfaces.IAuthorizationPolicy`` interface but will not work with\n  the new ``pyramid.interfaces.ISecurityPolicy``.\n  See https://github.com/Pylons/pyramid/pull/3465\n\n- Deprecated several ACL-related aspects of ``pyramid.security``. Equivalent\n  objects should now be imported from the ``pyramid.authorization`` namespace.\n  This includes:\n\n  - ``pyramid.security.Everyone``\n  - ``pyramid.security.Authenticated``\n  - ``pyramid.security.ALL_PERMISSIONS``\n  - ``pyramid.security.DENY_ALL``\n  - ``pyramid.security.ACLAllowed``\n  - ``pyramid.security.ACLDenied``\n\n  See https://github.com/Pylons/pyramid/pull/3563\n\n- Deprecated ``pyramid.session.PickleSerializer``.\n  See https://github.com/pylons/pyramid/issues/2709,\n  and https://github.com/pylons/pyramid/pull/3353,\n  and https://github.com/pylons/pyramid/pull/3413\n\nBackward Incompatibilities\n--------------------------\n\n- Drop support for Python 2.7, 3.4, and 3.5.\n  See https://github.com/Pylons/pyramid/pull/3421,\n  and https://github.com/Pylons/pyramid/pull/3547,\n  and https://github.com/Pylons/pyramid/pull/3634\n\n- Removed the ``pyramid.compat`` module. Integrators should use the ``six``\n  module or vendor shims they are using into their own codebases going forward.\n  https://github.com/Pylons/pyramid/pull/3421\n\n- ``pcreate`` and the builtin scaffolds have been removed in favor of\n  using the ``cookiecutter`` tool and the ``pyramid-cookiecutter-starter``\n  cookiecutter. The script and scaffolds were deprecated in Pyramid 1.8.\n  See https://github.com/Pylons/pyramid/pull/3406\n\n- Changed the default ``hashalg`` on\n  ``pyramid.authentication.AuthTktCookieHelper`` to ``sha512``.\n  See https://github.com/Pylons/pyramid/pull/3557\n\n- Removed ``pyramid.interfaces.ITemplateRenderer``. This interface was\n  deprecated since Pyramid 1.5 and was an interface\n  used by libraries like ``pyramid_mako`` and ``pyramid_chameleon`` but\n  provided no functionality within Pyramid itself.\n  See https://github.com/Pylons/pyramid/pull/3409\n\n- Removed ``pyramid.security.has_permission``,\n  ``pyramid.security.authenticated_userid``,\n  ``pyramid.security.unauthenticated_userid``, and\n  ``pyramid.security.effective_principals``. These methods were deprecated\n  in Pyramid 1.5 and all have equivalents available as properties on the\n  request. For example, ``request.authenticated_userid``.\n  See https://github.com/Pylons/pyramid/pull/3410\n\n- Removed support for supplying a media range to the ``accept`` predicate of\n  both ``pyramid.config.Configurator.add_view`` and\n  ``pyramid.config.Configurator.add_route``. These options were deprecated\n  in Pyramid 1.10 and WebOb 1.8 because they resulted in uncontrollable\n  matching that was not compliant with the RFC.\n  See https://github.com/Pylons/pyramid/pull/3411\n\n- Removed ``pyramid.session.UnencryptedCookieSessionFactoryConfig``. This\n  session factory was replaced with\n  ``pyramid.session.SignedCookieSessionFactory`` in Pyramid 1.5 and has been\n  deprecated since then.\n  See https://github.com/Pylons/pyramid/pull/3412\n\n- Removed ``pyramid.session.signed_serialize``, and\n  ``pyramid.session.signed_deserialize``. These methods were only used by\n  the now-removed ``pyramid.session.UnencryptedCookieSessionFactoryConfig``\n  and were coupled to the vulnerable pickle serialization format which could\n  lead to remove code execution if the secret key is compromised.\n  See https://github.com/Pylons/pyramid/pull/3412\n\n- Changed the default ``serializer`` on\n  ``pyramid.session.SignedCookieSessionFactory`` to use\n  ``pyramid.session.JSONSerializer`` instead of\n  ``pyramid.session.PickleSerializer``. Read \"Upgrading Session Serialization\"\n  in the \"What's New in Pyramid 2.0\" chapter of the documentation for more\n  information about why this change was made.\n  See https://github.com/Pylons/pyramid/pull/3413\n\n- ``pyramid.request.Request.invoke_exception_view`` will no longer be called\n  by the default execution policy.\n  See https://github.com/Pylons/pyramid/pull/3496\n\n- ``pyramid.config.Configurator.scan`` will no longer, by default, execute\n  Venusian decorator callbacks registered for categories other than\n  ``'pyramid'``. To find any decorator regardless of category, specify\n  ``config.scan(..., categories=None)``.\n  See https://github.com/Pylons/pyramid/pull/3510\n\n- The second argument to predicate factories has been changed from ``config``\n  to ``info``, an instance of ``pyramid.interfaces.IPredicateInfo``. This\n  limits the data available to predicates but still provides the package,\n  registry, settings and dotted-name resolver which should cover most use\n  cases and is largely backward compatible.\n  See https://github.com/Pylons/pyramid/pull/3514\n\n- Removed the ``check_csrf`` predicate. Instead, use\n  ``pyramid.config.Configurator.set_default_csrf_options`` and the\n  ``require_csrf`` view option to enable automatic CSRF checking.\n  See https://github.com/Pylons/pyramid/pull/3521\n\n- Update the default behavior of\n  ``pyramid.authenticationAuthTktAuthenticationPolicy`` and\n  ``pyramid.authentication.AuthTktCookieHelper`` to only set a single cookie\n  without a domain parameter when no other domain constraints are specified.\n  Prior to this change, ``wild_domain=False`` (the default) was effectively\n  treated the same as ``wild_domain=True``, in which a cookie was defined\n  such that browsers would use it both for the request's domain, as well as\n  any subdomain. In the new behavior, cookies will only affect the current\n  domain, and not subdomains, by default.\n  See https://github.com/Pylons/pyramid/pull/3587\n\nDocumentation Changes\n---------------------\n\n- Restore build of PDF on Read The Docs.\n  See https://github.com/Pylons/pyramid/issues/3290\n\n- Fix docs build for Sphinx 2.0.\n  See https://github.com/Pylons/pyramid/pull/3480\n\n- Significant updates to the wiki, wiki2 tutorials to demonstrate the new\n  security policy usage as well as a much more production-ready test harness.\n  See https://github.com/Pylons/pyramid/pull/3557\n",
            "header": {
                "file": {
                    "path": "CHANGES.rst"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "d2dbe071b",
                "new_commit_hash": "a8e4d6c61",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/CHANGES.rst"
            },
            "plus_file": {
                "path": "b/CHANGES.rst"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 1,
                            "length": 3
                        },
                        "new_range": {
                            "start": 1,
                            "length": 9
                        },
                        "section": ""
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "Unreleased",
                                "type": "added"
                            },
                            {
                                "content": "==========",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "- Break potential reference cycle between ``request`` and ``context``.",
                                "type": "added"
                            },
                            {
                                "content": "  See https://github.com/Pylons/pyramid/pull/3649",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "2.0b0 (2020-12-15)",
                                "type": "context"
                            },
                            {
                                "content": "==================",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "from zope.interface import implementer, providedBy\n\nfrom pyramid.events import (\n    BeforeTraversal,\n    ContextFound,\n    NewRequest,\n    NewResponse,\n)\nfrom pyramid.httpexceptions import HTTPNotFound\nfrom pyramid.interfaces import (\n    IDebugLogger,\n    IExecutionPolicy,\n    IRequest,\n    IRequestExtensions,\n    IRequestFactory,\n    IRootFactory,\n    IRouter,\n    IRouteRequest,\n    IRoutesMapper,\n    ITraverser,\n    ITweens,\n)\nfrom pyramid.request import Request, apply_request_extensions\nfrom pyramid.threadlocal import RequestContext\nfrom pyramid.traversal import DefaultRootFactory, ResourceTreeTraverser\nfrom pyramid.view import _call_view\n\n\n@implementer(IRouter)\nclass Router:\n\n    debug_notfound = False\n    debug_routematch = False\n\n    def __init__(self, registry):\n        q = registry.queryUtility\n        self.logger = q(IDebugLogger)\n        self.root_factory = q(IRootFactory, default=DefaultRootFactory)\n        self.routes_mapper = q(IRoutesMapper)\n        self.request_factory = q(IRequestFactory, default=Request)\n        self.request_extensions = q(IRequestExtensions)\n        self.execution_policy = q(\n            IExecutionPolicy, default=default_execution_policy\n        )\n        self.orig_handle_request = self.handle_request\n        tweens = q(ITweens)\n        if tweens is not None:\n            self.handle_request = tweens(self.handle_request, registry)\n        self.root_policy = self.root_factory  # b/w compat\n        self.registry = registry\n        settings = registry.settings\n        if settings is not None:\n            self.debug_notfound = settings['debug_notfound']\n            self.debug_routematch = settings['debug_routematch']\n\n    def handle_request(self, request):\n        attrs = request.__dict__\n        registry = attrs['registry']\n\n        request.request_iface = IRequest\n        context = None\n        routes_mapper = self.routes_mapper\n        debug_routematch = self.debug_routematch\n        adapters = registry.adapters\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n        logger = self.logger\n\n        has_listeners and notify(NewRequest(request))\n        # find the root object\n        root_factory = self.root_factory\n        if routes_mapper is not None:\n            info = routes_mapper(request)\n            match, route = info['match'], info['route']\n            if route is None:\n                if debug_routematch:\n                    msg = 'no route matched for url %s' % request.url\n                    logger and logger.debug(msg)\n            else:\n                attrs['matchdict'] = match\n                attrs['matched_route'] = route\n\n                if debug_routematch:\n                    msg = (\n                        'route matched for url %s; '\n                        'route_name: %r, '\n                        'path_info: %r, '\n                        'pattern: %r, '\n                        'matchdict: %r, '\n                        'predicates: %r'\n                        % (\n                            request.url,\n                            route.name,\n                            request.path_info,\n                            route.pattern,\n                            match,\n                            ', '.join([p.text() for p in route.predicates]),\n                        )\n                    )\n                    logger and logger.debug(msg)\n\n                request.request_iface = registry.queryUtility(\n                    IRouteRequest, name=route.name, default=IRequest\n                )\n\n                root_factory = route.factory or self.root_factory\n\n        # Notify anyone listening that we are about to start traversal\n        #\n        # Notify before creating root_factory in case we want to do something\n        # special on a route we may have matched. See\n        # https://github.com/Pylons/pyramid/pull/1876 for ideas of what is\n        # possible.\n        has_listeners and notify(BeforeTraversal(request))\n\n        # Create the root factory\n        root = root_factory(request)\n        attrs['root'] = root\n\n        # We are about to traverse and find a context\n        traverser = adapters.queryAdapter(root, ITraverser)\n        if traverser is None:\n            traverser = ResourceTreeTraverser(root)\n        tdict = traverser(request)\n\n        context, view_name, subpath, traversed, vroot, vroot_path = (\n            tdict['context'],\n            tdict['view_name'],\n            tdict['subpath'],\n            tdict['traversed'],\n            tdict['virtual_root'],\n            tdict['virtual_root_path'],\n        )\n\n        attrs.update(tdict)\n\n        # Notify anyone listening that we have a context and traversal is\n        # complete\n        has_listeners and notify(ContextFound(request))\n\n        # find a view callable\n        context_iface = providedBy(context)\n        response = _call_view(\n            registry, request, context, context_iface, view_name\n        )\n\n        if response is None:\n            if self.debug_notfound:\n                msg = (\n                    'debug_notfound of url %s; path_info: %r, '\n                    'context: %r, view_name: %r, subpath: %r, '\n                    'traversed: %r, root: %r, vroot: %r, '\n                    'vroot_path: %r'\n                    % (\n                        request.url,\n                        request.path_info,\n                        context,\n                        view_name,\n                        subpath,\n                        traversed,\n                        root,\n                        vroot,\n                        vroot_path,\n                    )\n                )\n                logger and logger.debug(msg)\n            else:\n                msg = request.path_info\n            raise HTTPNotFound(msg)\n\n        return response\n\n    def invoke_subrequest(self, request, use_tweens=False):\n        \"\"\"Obtain a response object from the Pyramid application based on\n        information in the ``request`` object provided.  The ``request``\n        object must be an object that implements the Pyramid request\n        interface (such as a :class:`pyramid.request.Request` instance).  If\n        ``use_tweens`` is ``True``, the request will be sent to the\n        :term:`tween` in the tween stack closest to the request ingress.  If\n        ``use_tweens`` is ``False``, the request will be sent to the main\n        router handler, and no tweens will be invoked.\n\n        See the API for pyramid.request for complete documentation.\n        \"\"\"\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        with RequestContext(request):\n            return self.invoke_request(request, _use_tweens=use_tweens)\n\n    def request_context(self, environ):\n        \"\"\"\n        Create a new request context from a WSGI environ.\n\n        The request context is used to push/pop the threadlocals required\n        when processing the request. It also contains an initialized\n        :class:`pyramid.interfaces.IRequest` instance using the registered\n        :class:`pyramid.interfaces.IRequestFactory`. The context may be\n        used as a context manager to control the threadlocal lifecycle:\n\n        .. code-block:: python\n\n            with router.request_context(environ) as request:\n                ...\n\n        Alternatively, the context may be used without the ``with`` statement\n        by manually invoking its ``begin()`` and ``end()`` methods.\n\n        .. code-block:: python\n\n            ctx = router.request_context(environ)\n            request = ctx.begin()\n            try:\n                ...\n            finally:\n                ctx.end()\n\n        \"\"\"\n        request = self.request_factory(environ)\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        return RequestContext(request)\n\n    def invoke_request(self, request, _use_tweens=True):\n        \"\"\"\n        Execute a request through the request processing pipeline and\n        return the generated response.\n\n        \"\"\"\n        registry = self.registry\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n\n        if _use_tweens:\n            handle_request = self.handle_request\n        else:\n            handle_request = self.orig_handle_request\n\n        try:\n            response = handle_request(request)\n\n            if request.response_callbacks:\n                request._process_response_callbacks(response)\n\n            has_listeners and notify(NewResponse(request, response))\n\n            return response\n\n        finally:\n            if request.finished_callbacks:\n                request._process_finished_callbacks()\n\n    def __call__(self, environ, start_response):\n        \"\"\"\n        Accept ``environ`` and ``start_response``; create a\n        :term:`request` and route the request to a :app:`Pyramid`\n        view based on introspection of :term:`view configuration`\n        within the application registry; call ``start_response`` and\n        return an iterable.\n        \"\"\"\n        response = self.execution_policy(environ, self)\n        return response(environ, start_response)\n\n\ndef default_execution_policy(environ, router):\n    with router.request_context(environ) as request:\n        return router.invoke_request(request)\n",
            "new_file_content": "from zope.interface import implementer, providedBy\n\nfrom pyramid.events import (\n    BeforeTraversal,\n    ContextFound,\n    NewRequest,\n    NewResponse,\n)\nfrom pyramid.httpexceptions import HTTPNotFound\nfrom pyramid.interfaces import (\n    IDebugLogger,\n    IExecutionPolicy,\n    IRequest,\n    IRequestExtensions,\n    IRequestFactory,\n    IRootFactory,\n    IRouter,\n    IRouteRequest,\n    IRoutesMapper,\n    ITraverser,\n    ITweens,\n)\nfrom pyramid.request import Request, apply_request_extensions\nfrom pyramid.threadlocal import RequestContext\nfrom pyramid.traversal import DefaultRootFactory, ResourceTreeTraverser\nfrom pyramid.view import _call_view\n\n\n@implementer(IRouter)\nclass Router:\n\n    debug_notfound = False\n    debug_routematch = False\n\n    def __init__(self, registry):\n        q = registry.queryUtility\n        self.logger = q(IDebugLogger)\n        self.root_factory = q(IRootFactory, default=DefaultRootFactory)\n        self.routes_mapper = q(IRoutesMapper)\n        self.request_factory = q(IRequestFactory, default=Request)\n        self.request_extensions = q(IRequestExtensions)\n        self.execution_policy = q(\n            IExecutionPolicy, default=default_execution_policy\n        )\n        self.orig_handle_request = self.handle_request\n        tweens = q(ITweens)\n        if tweens is not None:\n            self.handle_request = tweens(self.handle_request, registry)\n        self.root_policy = self.root_factory  # b/w compat\n        self.registry = registry\n        settings = registry.settings\n        if settings is not None:\n            self.debug_notfound = settings['debug_notfound']\n            self.debug_routematch = settings['debug_routematch']\n\n    def handle_request(self, request):\n        attrs = request.__dict__\n        registry = attrs['registry']\n\n        request.request_iface = IRequest\n        context = None\n        routes_mapper = self.routes_mapper\n        debug_routematch = self.debug_routematch\n        adapters = registry.adapters\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n        logger = self.logger\n\n        has_listeners and notify(NewRequest(request))\n        # find the root object\n        root_factory = self.root_factory\n        if routes_mapper is not None:\n            info = routes_mapper(request)\n            match, route = info['match'], info['route']\n            if route is None:\n                if debug_routematch:\n                    msg = 'no route matched for url %s' % request.url\n                    logger and logger.debug(msg)\n            else:\n                attrs['matchdict'] = match\n                attrs['matched_route'] = route\n\n                if debug_routematch:\n                    msg = (\n                        'route matched for url %s; '\n                        'route_name: %r, '\n                        'path_info: %r, '\n                        'pattern: %r, '\n                        'matchdict: %r, '\n                        'predicates: %r'\n                        % (\n                            request.url,\n                            route.name,\n                            request.path_info,\n                            route.pattern,\n                            match,\n                            ', '.join([p.text() for p in route.predicates]),\n                        )\n                    )\n                    logger and logger.debug(msg)\n\n                request.request_iface = registry.queryUtility(\n                    IRouteRequest, name=route.name, default=IRequest\n                )\n\n                root_factory = route.factory or self.root_factory\n\n        # Notify anyone listening that we are about to start traversal\n        #\n        # Notify before creating root_factory in case we want to do something\n        # special on a route we may have matched. See\n        # https://github.com/Pylons/pyramid/pull/1876 for ideas of what is\n        # possible.\n        has_listeners and notify(BeforeTraversal(request))\n\n        # Create the root factory\n        root = root_factory(request)\n        attrs['root'] = root\n\n        # We are about to traverse and find a context\n        traverser = adapters.queryAdapter(root, ITraverser)\n        if traverser is None:\n            traverser = ResourceTreeTraverser(root)\n        tdict = traverser(request)\n\n        context, view_name, subpath, traversed, vroot, vroot_path = (\n            tdict['context'],\n            tdict['view_name'],\n            tdict['subpath'],\n            tdict['traversed'],\n            tdict['virtual_root'],\n            tdict['virtual_root_path'],\n        )\n\n        attrs.update(tdict)\n\n        # Notify anyone listening that we have a context and traversal is\n        # complete\n        has_listeners and notify(ContextFound(request))\n\n        # find a view callable\n        context_iface = providedBy(context)\n        response = _call_view(\n            registry, request, context, context_iface, view_name\n        )\n\n        if response is None:\n            if self.debug_notfound:\n                msg = (\n                    'debug_notfound of url %s; path_info: %r, '\n                    'context: %r, view_name: %r, subpath: %r, '\n                    'traversed: %r, root: %r, vroot: %r, '\n                    'vroot_path: %r'\n                    % (\n                        request.url,\n                        request.path_info,\n                        context,\n                        view_name,\n                        subpath,\n                        traversed,\n                        root,\n                        vroot,\n                        vroot_path,\n                    )\n                )\n                logger and logger.debug(msg)\n            else:\n                msg = request.path_info\n            raise HTTPNotFound(msg)\n\n        return response\n\n    def invoke_subrequest(self, request, use_tweens=False):\n        \"\"\"Obtain a response object from the Pyramid application based on\n        information in the ``request`` object provided.  The ``request``\n        object must be an object that implements the Pyramid request\n        interface (such as a :class:`pyramid.request.Request` instance).  If\n        ``use_tweens`` is ``True``, the request will be sent to the\n        :term:`tween` in the tween stack closest to the request ingress.  If\n        ``use_tweens`` is ``False``, the request will be sent to the main\n        router handler, and no tweens will be invoked.\n\n        See the API for pyramid.request for complete documentation.\n        \"\"\"\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        with RequestContext(request):\n            return self.invoke_request(request, _use_tweens=use_tweens)\n\n    def request_context(self, environ):\n        \"\"\"\n        Create a new request context from a WSGI environ.\n\n        The request context is used to push/pop the threadlocals required\n        when processing the request. It also contains an initialized\n        :class:`pyramid.interfaces.IRequest` instance using the registered\n        :class:`pyramid.interfaces.IRequestFactory`. The context may be\n        used as a context manager to control the threadlocal lifecycle:\n\n        .. code-block:: python\n\n            with router.request_context(environ) as request:\n                ...\n\n        Alternatively, the context may be used without the ``with`` statement\n        by manually invoking its ``begin()`` and ``end()`` methods.\n\n        .. code-block:: python\n\n            ctx = router.request_context(environ)\n            request = ctx.begin()\n            try:\n                ...\n            finally:\n                ctx.end()\n\n        \"\"\"\n        request = self.request_factory(environ)\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        return RequestContext(request)\n\n    def invoke_request(self, request, _use_tweens=True):\n        \"\"\"\n        Execute a request through the request processing pipeline and\n        return the generated response.\n\n        \"\"\"\n        registry = self.registry\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n\n        if _use_tweens:\n            handle_request = self.handle_request\n        else:\n            handle_request = self.orig_handle_request\n\n        try:\n            response = handle_request(request)\n\n            if request.response_callbacks:\n                request._process_response_callbacks(response)\n\n            has_listeners and notify(NewResponse(request, response))\n\n            return response\n\n        finally:\n            self.finish_request(request)\n\n    def finish_request(self, request):\n        if request.finished_callbacks:\n            request._process_finished_callbacks()\n        request.__dict__.pop('context', None)  # Break potential ref cycle\n\n    def __call__(self, environ, start_response):\n        \"\"\"\n        Accept ``environ`` and ``start_response``; create a\n        :term:`request` and route the request to a :app:`Pyramid`\n        view based on introspection of :term:`view configuration`\n        within the application registry; call ``start_response`` and\n        return an iterable.\n        \"\"\"\n        response = self.execution_policy(environ, self)\n        return response(environ, start_response)\n\n\ndef default_execution_policy(environ, router):\n    with router.request_context(environ) as request:\n        return router.invoke_request(request)\n",
            "header": {
                "file": {
                    "path": "src/pyramid/router.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "644a6a395",
                "new_commit_hash": "61660c41b",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/src/pyramid/router.py"
            },
            "plus_file": {
                "path": "b/src/pyramid/router.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 252,
                            "length": 8
                        },
                        "new_range": {
                            "start": 252,
                            "length": 12
                        },
                        "section": "class Router:"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "            return response",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        finally:",
                                "type": "context"
                            },
                            {
                                "content": "            if request.finished_callbacks:",
                                "type": "deleted"
                            },
                            {
                                "content": "                request._process_finished_callbacks()",
                                "type": "deleted"
                            },
                            {
                                "content": "            self.finish_request(request)",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def finish_request(self, request):",
                                "type": "added"
                            },
                            {
                                "content": "        if request.finished_callbacks:",
                                "type": "added"
                            },
                            {
                                "content": "            request._process_finished_callbacks()",
                                "type": "added"
                            },
                            {
                                "content": "        request.__dict__.pop('context', None)  # Break potential ref cycle",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def __call__(self, environ, start_response):",
                                "type": "context"
                            },
                            {
                                "content": "        \"\"\"",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "src/pyramid/router.py",
                            "type": "method",
                            "name": "Router.invoke_request",
                            "content": "class Router:\n\n    debug_notfound = False\n    debug_routematch = False\n\n    def __init__(self, registry):\n        q = registry.queryUtility\n        self.logger = q(IDebugLogger)\n        self.root_factory = q(IRootFactory, default=DefaultRootFactory)\n        self.routes_mapper = q(IRoutesMapper)\n        self.request_factory = q(IRequestFactory, default=Request)\n        self.request_extensions = q(IRequestExtensions)\n        self.execution_policy = q(\n            IExecutionPolicy, default=default_execution_policy\n        )\n        self.orig_handle_request = self.handle_request\n        tweens = q(ITweens)\n        if tweens is not None:\n            self.handle_request = tweens(self.handle_request, registry)\n        self.root_policy = self.root_factory  # b/w compat\n        self.registry = registry\n        settings = registry.settings\n        if settings is not None:\n            self.debug_notfound = settings['debug_notfound']\n            self.debug_routematch = settings['debug_routematch']\n\n    def handle_request(self, request):\n        attrs = request.__dict__\n        registry = attrs['registry']\n\n        request.request_iface = IRequest\n        context = None\n        routes_mapper = self.routes_mapper\n        debug_routematch = self.debug_routematch\n        adapters = registry.adapters\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n        logger = self.logger\n\n        has_listeners and notify(NewRequest(request))\n        # find the root object\n        root_factory = self.root_factory\n        if routes_mapper is not None:\n            info = routes_mapper(request)\n            match, route = info['match'], info['route']\n            if route is None:\n                if debug_routematch:\n                    msg = 'no route matched for url %s' % request.url\n                    logger and logger.debug(msg)\n            else:\n                attrs['matchdict'] = match\n                attrs['matched_route'] = route\n\n                if debug_routematch:\n                    msg = (\n                        'route matched for url %s; '\n                        'route_name: %r, '\n                        'path_info: %r, '\n                        'pattern: %r, '\n                        'matchdict: %r, '\n                        'predicates: %r'\n                        % (\n                            request.url,\n                            route.name,\n                            request.path_info,\n                            route.pattern,\n                            match,\n                            ', '.join([p.text() for p in route.predicates]),\n                        )\n                    )\n                    logger and logger.debug(msg)\n\n                request.request_iface = registry.queryUtility(\n                    IRouteRequest, name=route.name, default=IRequest\n                )\n\n                root_factory = route.factory or self.root_factory\n\n        # Notify anyone listening that we are about to start traversal\n        #\n        # Notify before creating root_factory in case we want to do something\n        # special on a route we may have matched. See\n        # https://github.com/Pylons/pyramid/pull/1876 for ideas of what is\n        # possible.\n        has_listeners and notify(BeforeTraversal(request))\n\n        # Create the root factory\n        root = root_factory(request)\n        attrs['root'] = root\n\n        # We are about to traverse and find a context\n        traverser = adapters.queryAdapter(root, ITraverser)\n        if traverser is None:\n            traverser = ResourceTreeTraverser(root)\n        tdict = traverser(request)\n\n        context, view_name, subpath, traversed, vroot, vroot_path = (\n            tdict['context'],\n            tdict['view_name'],\n            tdict['subpath'],\n            tdict['traversed'],\n            tdict['virtual_root'],\n            tdict['virtual_root_path'],\n        )\n\n        attrs.update(tdict)\n\n        # Notify anyone listening that we have a context and traversal is\n        # complete\n        has_listeners and notify(ContextFound(request))\n\n        # find a view callable\n        context_iface = providedBy(context)\n        response = _call_view(\n            registry, request, context, context_iface, view_name\n        )\n\n        if response is None:\n            if self.debug_notfound:\n                msg = (\n                    'debug_notfound of url %s; path_info: %r, '\n                    'context: %r, view_name: %r, subpath: %r, '\n                    'traversed: %r, root: %r, vroot: %r, '\n                    'vroot_path: %r'\n                    % (\n                        request.url,\n                        request.path_info,\n                        context,\n                        view_name,\n                        subpath,\n                        traversed,\n                        root,\n                        vroot,\n                        vroot_path,\n                    )\n                )\n                logger and logger.debug(msg)\n            else:\n                msg = request.path_info\n            raise HTTPNotFound(msg)\n\n        return response\n\n    def invoke_subrequest(self, request, use_tweens=False):\n        \"\"\"Obtain a response object from the Pyramid application based on\n        information in the ``request`` object provided.  The ``request``\n        object must be an object that implements the Pyramid request\n        interface (such as a :class:`pyramid.request.Request` instance).  If\n        ``use_tweens`` is ``True``, the request will be sent to the\n        :term:`tween` in the tween stack closest to the request ingress.  If\n        ``use_tweens`` is ``False``, the request will be sent to the main\n        router handler, and no tweens will be invoked.\n\n        See the API for pyramid.request for complete documentation.\n        \"\"\"\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        with RequestContext(request):\n            return self.invoke_request(request, _use_tweens=use_tweens)\n\n    def request_context(self, environ):\n        \"\"\"\n        Create a new request context from a WSGI environ.\n\n        The request context is used to push/pop the threadlocals required\n        when processing the request. It also contains an initialized\n        :class:`pyramid.interfaces.IRequest` instance using the registered\n        :class:`pyramid.interfaces.IRequestFactory`. The context may be\n        used as a context manager to control the threadlocal lifecycle:\n\n        .. code-block:: python\n\n            with router.request_context(environ) as request:\n                ...\n\n        Alternatively, the context may be used without the ``with`` statement\n        by manually invoking its ``begin()`` and ``end()`` methods.\n\n        .. code-block:: python\n\n            ctx = router.request_context(environ)\n            request = ctx.begin()\n            try:\n                ...\n            finally:\n                ctx.end()\n\n        \"\"\"\n        request = self.request_factory(environ)\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        return RequestContext(request)\n\n    def invoke_request(self, request, _use_tweens=True):\n        \"\"\"\n        Execute a request through the request processing pipeline and\n        return the generated response.\n\n        \"\"\"\n        registry = self.registry\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n\n        if _use_tweens:\n            handle_request = self.handle_request\n        else:\n            handle_request = self.orig_handle_request\n\n        try:\n            response = handle_request(request)\n\n            if request.response_callbacks:\n                request._process_response_callbacks(response)\n\n            has_listeners and notify(NewResponse(request, response))\n\n            return response\n\n        finally:\n            if request.finished_callbacks:\n                request._process_finished_callbacks()\n\n    def __call__(self, environ, start_response):\n        \"\"\"\n        Accept ``environ`` and ``start_response``; create a\n        :term:`request` and route the request to a :app:`Pyramid`\n        view based on introspection of :term:`view configuration`\n        within the application registry; call ``start_response`` and\n        return an iterable.\n        \"\"\"\n        response = self.execution_policy(environ, self)\n        return response(environ, start_response)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 229,
                            "end_lineno": 256,
                            "parent": {
                                "file_name": "src/pyramid/router.py",
                                "type": "class",
                                "name": "Router",
                                "content": "class Router:\n\n    debug_notfound = False\n    debug_routematch = False\n\n    def __init__(self, registry):\n        q = registry.queryUtility\n        self.logger = q(IDebugLogger)\n        self.root_factory = q(IRootFactory, default=DefaultRootFactory)\n        self.routes_mapper = q(IRoutesMapper)\n        self.request_factory = q(IRequestFactory, default=Request)\n        self.request_extensions = q(IRequestExtensions)\n        self.execution_policy = q(\n            IExecutionPolicy, default=default_execution_policy\n        )\n        self.orig_handle_request = self.handle_request\n        tweens = q(ITweens)\n        if tweens is not None:\n            self.handle_request = tweens(self.handle_request, registry)\n        self.root_policy = self.root_factory  # b/w compat\n        self.registry = registry\n        settings = registry.settings\n        if settings is not None:\n            self.debug_notfound = settings['debug_notfound']\n            self.debug_routematch = settings['debug_routematch']\n\n    def handle_request(self, request):\n        attrs = request.__dict__\n        registry = attrs['registry']\n\n        request.request_iface = IRequest\n        context = None\n        routes_mapper = self.routes_mapper\n        debug_routematch = self.debug_routematch\n        adapters = registry.adapters\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n        logger = self.logger\n\n        has_listeners and notify(NewRequest(request))\n        # find the root object\n        root_factory = self.root_factory\n        if routes_mapper is not None:\n            info = routes_mapper(request)\n            match, route = info['match'], info['route']\n            if route is None:\n                if debug_routematch:\n                    msg = 'no route matched for url %s' % request.url\n                    logger and logger.debug(msg)\n            else:\n                attrs['matchdict'] = match\n                attrs['matched_route'] = route\n\n                if debug_routematch:\n                    msg = (\n                        'route matched for url %s; '\n                        'route_name: %r, '\n                        'path_info: %r, '\n                        'pattern: %r, '\n                        'matchdict: %r, '\n                        'predicates: %r'\n                        % (\n                            request.url,\n                            route.name,\n                            request.path_info,\n                            route.pattern,\n                            match,\n                            ', '.join([p.text() for p in route.predicates]),\n                        )\n                    )\n                    logger and logger.debug(msg)\n\n                request.request_iface = registry.queryUtility(\n                    IRouteRequest, name=route.name, default=IRequest\n                )\n\n                root_factory = route.factory or self.root_factory\n\n        # Notify anyone listening that we are about to start traversal\n        #\n        # Notify before creating root_factory in case we want to do something\n        # special on a route we may have matched. See\n        # https://github.com/Pylons/pyramid/pull/1876 for ideas of what is\n        # possible.\n        has_listeners and notify(BeforeTraversal(request))\n\n        # Create the root factory\n        root = root_factory(request)\n        attrs['root'] = root\n\n        # We are about to traverse and find a context\n        traverser = adapters.queryAdapter(root, ITraverser)\n        if traverser is None:\n            traverser = ResourceTreeTraverser(root)\n        tdict = traverser(request)\n\n        context, view_name, subpath, traversed, vroot, vroot_path = (\n            tdict['context'],\n            tdict['view_name'],\n            tdict['subpath'],\n            tdict['traversed'],\n            tdict['virtual_root'],\n            tdict['virtual_root_path'],\n        )\n\n        attrs.update(tdict)\n\n        # Notify anyone listening that we have a context and traversal is\n        # complete\n        has_listeners and notify(ContextFound(request))\n\n        # find a view callable\n        context_iface = providedBy(context)\n        response = _call_view(\n            registry, request, context, context_iface, view_name\n        )\n\n        if response is None:\n            if self.debug_notfound:\n                msg = (\n                    'debug_notfound of url %s; path_info: %r, '\n                    'context: %r, view_name: %r, subpath: %r, '\n                    'traversed: %r, root: %r, vroot: %r, '\n                    'vroot_path: %r'\n                    % (\n                        request.url,\n                        request.path_info,\n                        context,\n                        view_name,\n                        subpath,\n                        traversed,\n                        root,\n                        vroot,\n                        vroot_path,\n                    )\n                )\n                logger and logger.debug(msg)\n            else:\n                msg = request.path_info\n            raise HTTPNotFound(msg)\n\n        return response\n\n    def invoke_subrequest(self, request, use_tweens=False):\n        \"\"\"Obtain a response object from the Pyramid application based on\n        information in the ``request`` object provided.  The ``request``\n        object must be an object that implements the Pyramid request\n        interface (such as a :class:`pyramid.request.Request` instance).  If\n        ``use_tweens`` is ``True``, the request will be sent to the\n        :term:`tween` in the tween stack closest to the request ingress.  If\n        ``use_tweens`` is ``False``, the request will be sent to the main\n        router handler, and no tweens will be invoked.\n\n        See the API for pyramid.request for complete documentation.\n        \"\"\"\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        with RequestContext(request):\n            return self.invoke_request(request, _use_tweens=use_tweens)\n\n    def request_context(self, environ):\n        \"\"\"\n        Create a new request context from a WSGI environ.\n\n        The request context is used to push/pop the threadlocals required\n        when processing the request. It also contains an initialized\n        :class:`pyramid.interfaces.IRequest` instance using the registered\n        :class:`pyramid.interfaces.IRequestFactory`. The context may be\n        used as a context manager to control the threadlocal lifecycle:\n\n        .. code-block:: python\n\n            with router.request_context(environ) as request:\n                ...\n\n        Alternatively, the context may be used without the ``with`` statement\n        by manually invoking its ``begin()`` and ``end()`` methods.\n\n        .. code-block:: python\n\n            ctx = router.request_context(environ)\n            request = ctx.begin()\n            try:\n                ...\n            finally:\n                ctx.end()\n\n        \"\"\"\n        request = self.request_factory(environ)\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        return RequestContext(request)\n\n    def invoke_request(self, request, _use_tweens=True):\n        \"\"\"\n        Execute a request through the request processing pipeline and\n        return the generated response.\n\n        \"\"\"\n        registry = self.registry\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n\n        if _use_tweens:\n            handle_request = self.handle_request\n        else:\n            handle_request = self.orig_handle_request\n\n        try:\n            response = handle_request(request)\n\n            if request.response_callbacks:\n                request._process_response_callbacks(response)\n\n            has_listeners and notify(NewResponse(request, response))\n\n            return response\n\n        finally:\n            if request.finished_callbacks:\n                request._process_finished_callbacks()\n\n    def __call__(self, environ, start_response):\n        \"\"\"\n        Accept ``environ`` and ``start_response``; create a\n        :term:`request` and route the request to a :app:`Pyramid`\n        view based on introspection of :term:`view configuration`\n        within the application registry; call ``start_response`` and\n        return an iterable.\n        \"\"\"\n        response = self.execution_policy(environ, self)\n        return response(environ, start_response)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 30,
                                "end_lineno": 267,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "src/pyramid/router.py",
                            "type": "class",
                            "name": "Router",
                            "content": "class Router:\n\n    debug_notfound = False\n    debug_routematch = False\n\n    def __init__(self, registry):\n        q = registry.queryUtility\n        self.logger = q(IDebugLogger)\n        self.root_factory = q(IRootFactory, default=DefaultRootFactory)\n        self.routes_mapper = q(IRoutesMapper)\n        self.request_factory = q(IRequestFactory, default=Request)\n        self.request_extensions = q(IRequestExtensions)\n        self.execution_policy = q(\n            IExecutionPolicy, default=default_execution_policy\n        )\n        self.orig_handle_request = self.handle_request\n        tweens = q(ITweens)\n        if tweens is not None:\n            self.handle_request = tweens(self.handle_request, registry)\n        self.root_policy = self.root_factory  # b/w compat\n        self.registry = registry\n        settings = registry.settings\n        if settings is not None:\n            self.debug_notfound = settings['debug_notfound']\n            self.debug_routematch = settings['debug_routematch']\n\n    def handle_request(self, request):\n        attrs = request.__dict__\n        registry = attrs['registry']\n\n        request.request_iface = IRequest\n        context = None\n        routes_mapper = self.routes_mapper\n        debug_routematch = self.debug_routematch\n        adapters = registry.adapters\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n        logger = self.logger\n\n        has_listeners and notify(NewRequest(request))\n        # find the root object\n        root_factory = self.root_factory\n        if routes_mapper is not None:\n            info = routes_mapper(request)\n            match, route = info['match'], info['route']\n            if route is None:\n                if debug_routematch:\n                    msg = 'no route matched for url %s' % request.url\n                    logger and logger.debug(msg)\n            else:\n                attrs['matchdict'] = match\n                attrs['matched_route'] = route\n\n                if debug_routematch:\n                    msg = (\n                        'route matched for url %s; '\n                        'route_name: %r, '\n                        'path_info: %r, '\n                        'pattern: %r, '\n                        'matchdict: %r, '\n                        'predicates: %r'\n                        % (\n                            request.url,\n                            route.name,\n                            request.path_info,\n                            route.pattern,\n                            match,\n                            ', '.join([p.text() for p in route.predicates]),\n                        )\n                    )\n                    logger and logger.debug(msg)\n\n                request.request_iface = registry.queryUtility(\n                    IRouteRequest, name=route.name, default=IRequest\n                )\n\n                root_factory = route.factory or self.root_factory\n\n        # Notify anyone listening that we are about to start traversal\n        #\n        # Notify before creating root_factory in case we want to do something\n        # special on a route we may have matched. See\n        # https://github.com/Pylons/pyramid/pull/1876 for ideas of what is\n        # possible.\n        has_listeners and notify(BeforeTraversal(request))\n\n        # Create the root factory\n        root = root_factory(request)\n        attrs['root'] = root\n\n        # We are about to traverse and find a context\n        traverser = adapters.queryAdapter(root, ITraverser)\n        if traverser is None:\n            traverser = ResourceTreeTraverser(root)\n        tdict = traverser(request)\n\n        context, view_name, subpath, traversed, vroot, vroot_path = (\n            tdict['context'],\n            tdict['view_name'],\n            tdict['subpath'],\n            tdict['traversed'],\n            tdict['virtual_root'],\n            tdict['virtual_root_path'],\n        )\n\n        attrs.update(tdict)\n\n        # Notify anyone listening that we have a context and traversal is\n        # complete\n        has_listeners and notify(ContextFound(request))\n\n        # find a view callable\n        context_iface = providedBy(context)\n        response = _call_view(\n            registry, request, context, context_iface, view_name\n        )\n\n        if response is None:\n            if self.debug_notfound:\n                msg = (\n                    'debug_notfound of url %s; path_info: %r, '\n                    'context: %r, view_name: %r, subpath: %r, '\n                    'traversed: %r, root: %r, vroot: %r, '\n                    'vroot_path: %r'\n                    % (\n                        request.url,\n                        request.path_info,\n                        context,\n                        view_name,\n                        subpath,\n                        traversed,\n                        root,\n                        vroot,\n                        vroot_path,\n                    )\n                )\n                logger and logger.debug(msg)\n            else:\n                msg = request.path_info\n            raise HTTPNotFound(msg)\n\n        return response\n\n    def invoke_subrequest(self, request, use_tweens=False):\n        \"\"\"Obtain a response object from the Pyramid application based on\n        information in the ``request`` object provided.  The ``request``\n        object must be an object that implements the Pyramid request\n        interface (such as a :class:`pyramid.request.Request` instance).  If\n        ``use_tweens`` is ``True``, the request will be sent to the\n        :term:`tween` in the tween stack closest to the request ingress.  If\n        ``use_tweens`` is ``False``, the request will be sent to the main\n        router handler, and no tweens will be invoked.\n\n        See the API for pyramid.request for complete documentation.\n        \"\"\"\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        with RequestContext(request):\n            return self.invoke_request(request, _use_tweens=use_tweens)\n\n    def request_context(self, environ):\n        \"\"\"\n        Create a new request context from a WSGI environ.\n\n        The request context is used to push/pop the threadlocals required\n        when processing the request. It also contains an initialized\n        :class:`pyramid.interfaces.IRequest` instance using the registered\n        :class:`pyramid.interfaces.IRequestFactory`. The context may be\n        used as a context manager to control the threadlocal lifecycle:\n\n        .. code-block:: python\n\n            with router.request_context(environ) as request:\n                ...\n\n        Alternatively, the context may be used without the ``with`` statement\n        by manually invoking its ``begin()`` and ``end()`` methods.\n\n        .. code-block:: python\n\n            ctx = router.request_context(environ)\n            request = ctx.begin()\n            try:\n                ...\n            finally:\n                ctx.end()\n\n        \"\"\"\n        request = self.request_factory(environ)\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        return RequestContext(request)\n\n    def invoke_request(self, request, _use_tweens=True):\n        \"\"\"\n        Execute a request through the request processing pipeline and\n        return the generated response.\n\n        \"\"\"\n        registry = self.registry\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n\n        if _use_tweens:\n            handle_request = self.handle_request\n        else:\n            handle_request = self.orig_handle_request\n\n        try:\n            response = handle_request(request)\n\n            if request.response_callbacks:\n                request._process_response_callbacks(response)\n\n            has_listeners and notify(NewResponse(request, response))\n\n            return response\n\n        finally:\n            if request.finished_callbacks:\n                request._process_finished_callbacks()\n\n    def __call__(self, environ, start_response):\n        \"\"\"\n        Accept ``environ`` and ``start_response``; create a\n        :term:`request` and route the request to a :app:`Pyramid`\n        view based on introspection of :term:`view configuration`\n        within the application registry; call ``start_response`` and\n        return an iterable.\n        \"\"\"\n        response = self.execution_policy(environ, self)\n        return response(environ, start_response)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 30,
                            "end_lineno": 267,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "src/pyramid/router.py",
                            "type": "method",
                            "name": "Router.finish_request",
                            "content": "class Router:\n\n    debug_notfound = False\n    debug_routematch = False\n\n    def __init__(self, registry):\n        q = registry.queryUtility\n        self.logger = q(IDebugLogger)\n        self.root_factory = q(IRootFactory, default=DefaultRootFactory)\n        self.routes_mapper = q(IRoutesMapper)\n        self.request_factory = q(IRequestFactory, default=Request)\n        self.request_extensions = q(IRequestExtensions)\n        self.execution_policy = q(\n            IExecutionPolicy, default=default_execution_policy\n        )\n        self.orig_handle_request = self.handle_request\n        tweens = q(ITweens)\n        if tweens is not None:\n            self.handle_request = tweens(self.handle_request, registry)\n        self.root_policy = self.root_factory  # b/w compat\n        self.registry = registry\n        settings = registry.settings\n        if settings is not None:\n            self.debug_notfound = settings['debug_notfound']\n            self.debug_routematch = settings['debug_routematch']\n\n    def handle_request(self, request):\n        attrs = request.__dict__\n        registry = attrs['registry']\n\n        request.request_iface = IRequest\n        context = None\n        routes_mapper = self.routes_mapper\n        debug_routematch = self.debug_routematch\n        adapters = registry.adapters\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n        logger = self.logger\n\n        has_listeners and notify(NewRequest(request))\n        # find the root object\n        root_factory = self.root_factory\n        if routes_mapper is not None:\n            info = routes_mapper(request)\n            match, route = info['match'], info['route']\n            if route is None:\n                if debug_routematch:\n                    msg = 'no route matched for url %s' % request.url\n                    logger and logger.debug(msg)\n            else:\n                attrs['matchdict'] = match\n                attrs['matched_route'] = route\n\n                if debug_routematch:\n                    msg = (\n                        'route matched for url %s; '\n                        'route_name: %r, '\n                        'path_info: %r, '\n                        'pattern: %r, '\n                        'matchdict: %r, '\n                        'predicates: %r'\n                        % (\n                            request.url,\n                            route.name,\n                            request.path_info,\n                            route.pattern,\n                            match,\n                            ', '.join([p.text() for p in route.predicates]),\n                        )\n                    )\n                    logger and logger.debug(msg)\n\n                request.request_iface = registry.queryUtility(\n                    IRouteRequest, name=route.name, default=IRequest\n                )\n\n                root_factory = route.factory or self.root_factory\n\n        # Notify anyone listening that we are about to start traversal\n        #\n        # Notify before creating root_factory in case we want to do something\n        # special on a route we may have matched. See\n        # https://github.com/Pylons/pyramid/pull/1876 for ideas of what is\n        # possible.\n        has_listeners and notify(BeforeTraversal(request))\n\n        # Create the root factory\n        root = root_factory(request)\n        attrs['root'] = root\n\n        # We are about to traverse and find a context\n        traverser = adapters.queryAdapter(root, ITraverser)\n        if traverser is None:\n            traverser = ResourceTreeTraverser(root)\n        tdict = traverser(request)\n\n        context, view_name, subpath, traversed, vroot, vroot_path = (\n            tdict['context'],\n            tdict['view_name'],\n            tdict['subpath'],\n            tdict['traversed'],\n            tdict['virtual_root'],\n            tdict['virtual_root_path'],\n        )\n\n        attrs.update(tdict)\n\n        # Notify anyone listening that we have a context and traversal is\n        # complete\n        has_listeners and notify(ContextFound(request))\n\n        # find a view callable\n        context_iface = providedBy(context)\n        response = _call_view(\n            registry, request, context, context_iface, view_name\n        )\n\n        if response is None:\n            if self.debug_notfound:\n                msg = (\n                    'debug_notfound of url %s; path_info: %r, '\n                    'context: %r, view_name: %r, subpath: %r, '\n                    'traversed: %r, root: %r, vroot: %r, '\n                    'vroot_path: %r'\n                    % (\n                        request.url,\n                        request.path_info,\n                        context,\n                        view_name,\n                        subpath,\n                        traversed,\n                        root,\n                        vroot,\n                        vroot_path,\n                    )\n                )\n                logger and logger.debug(msg)\n            else:\n                msg = request.path_info\n            raise HTTPNotFound(msg)\n\n        return response\n\n    def invoke_subrequest(self, request, use_tweens=False):\n        \"\"\"Obtain a response object from the Pyramid application based on\n        information in the ``request`` object provided.  The ``request``\n        object must be an object that implements the Pyramid request\n        interface (such as a :class:`pyramid.request.Request` instance).  If\n        ``use_tweens`` is ``True``, the request will be sent to the\n        :term:`tween` in the tween stack closest to the request ingress.  If\n        ``use_tweens`` is ``False``, the request will be sent to the main\n        router handler, and no tweens will be invoked.\n\n        See the API for pyramid.request for complete documentation.\n        \"\"\"\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        with RequestContext(request):\n            return self.invoke_request(request, _use_tweens=use_tweens)\n\n    def request_context(self, environ):\n        \"\"\"\n        Create a new request context from a WSGI environ.\n\n        The request context is used to push/pop the threadlocals required\n        when processing the request. It also contains an initialized\n        :class:`pyramid.interfaces.IRequest` instance using the registered\n        :class:`pyramid.interfaces.IRequestFactory`. The context may be\n        used as a context manager to control the threadlocal lifecycle:\n\n        .. code-block:: python\n\n            with router.request_context(environ) as request:\n                ...\n\n        Alternatively, the context may be used without the ``with`` statement\n        by manually invoking its ``begin()`` and ``end()`` methods.\n\n        .. code-block:: python\n\n            ctx = router.request_context(environ)\n            request = ctx.begin()\n            try:\n                ...\n            finally:\n                ctx.end()\n\n        \"\"\"\n        request = self.request_factory(environ)\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        return RequestContext(request)\n\n    def invoke_request(self, request, _use_tweens=True):\n        \"\"\"\n        Execute a request through the request processing pipeline and\n        return the generated response.\n\n        \"\"\"\n        registry = self.registry\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n\n        if _use_tweens:\n            handle_request = self.handle_request\n        else:\n            handle_request = self.orig_handle_request\n\n        try:\n            response = handle_request(request)\n\n            if request.response_callbacks:\n                request._process_response_callbacks(response)\n\n            has_listeners and notify(NewResponse(request, response))\n\n            return response\n\n        finally:\n            self.finish_request(request)\n\n    def finish_request(self, request):\n        if request.finished_callbacks:\n            request._process_finished_callbacks()\n        request.__dict__.pop('context', None)  # Break potential ref cycle\n\n    def __call__(self, environ, start_response):\n        \"\"\"\n        Accept ``environ`` and ``start_response``; create a\n        :term:`request` and route the request to a :app:`Pyramid`\n        view based on introspection of :term:`view configuration`\n        within the application registry; call ``start_response`` and\n        return an iterable.\n        \"\"\"\n        response = self.execution_policy(environ, self)\n        return response(environ, start_response)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 257,
                            "end_lineno": 260,
                            "parent": {
                                "file_name": "src/pyramid/router.py",
                                "type": "class",
                                "name": "Router",
                                "content": "class Router:\n\n    debug_notfound = False\n    debug_routematch = False\n\n    def __init__(self, registry):\n        q = registry.queryUtility\n        self.logger = q(IDebugLogger)\n        self.root_factory = q(IRootFactory, default=DefaultRootFactory)\n        self.routes_mapper = q(IRoutesMapper)\n        self.request_factory = q(IRequestFactory, default=Request)\n        self.request_extensions = q(IRequestExtensions)\n        self.execution_policy = q(\n            IExecutionPolicy, default=default_execution_policy\n        )\n        self.orig_handle_request = self.handle_request\n        tweens = q(ITweens)\n        if tweens is not None:\n            self.handle_request = tweens(self.handle_request, registry)\n        self.root_policy = self.root_factory  # b/w compat\n        self.registry = registry\n        settings = registry.settings\n        if settings is not None:\n            self.debug_notfound = settings['debug_notfound']\n            self.debug_routematch = settings['debug_routematch']\n\n    def handle_request(self, request):\n        attrs = request.__dict__\n        registry = attrs['registry']\n\n        request.request_iface = IRequest\n        context = None\n        routes_mapper = self.routes_mapper\n        debug_routematch = self.debug_routematch\n        adapters = registry.adapters\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n        logger = self.logger\n\n        has_listeners and notify(NewRequest(request))\n        # find the root object\n        root_factory = self.root_factory\n        if routes_mapper is not None:\n            info = routes_mapper(request)\n            match, route = info['match'], info['route']\n            if route is None:\n                if debug_routematch:\n                    msg = 'no route matched for url %s' % request.url\n                    logger and logger.debug(msg)\n            else:\n                attrs['matchdict'] = match\n                attrs['matched_route'] = route\n\n                if debug_routematch:\n                    msg = (\n                        'route matched for url %s; '\n                        'route_name: %r, '\n                        'path_info: %r, '\n                        'pattern: %r, '\n                        'matchdict: %r, '\n                        'predicates: %r'\n                        % (\n                            request.url,\n                            route.name,\n                            request.path_info,\n                            route.pattern,\n                            match,\n                            ', '.join([p.text() for p in route.predicates]),\n                        )\n                    )\n                    logger and logger.debug(msg)\n\n                request.request_iface = registry.queryUtility(\n                    IRouteRequest, name=route.name, default=IRequest\n                )\n\n                root_factory = route.factory or self.root_factory\n\n        # Notify anyone listening that we are about to start traversal\n        #\n        # Notify before creating root_factory in case we want to do something\n        # special on a route we may have matched. See\n        # https://github.com/Pylons/pyramid/pull/1876 for ideas of what is\n        # possible.\n        has_listeners and notify(BeforeTraversal(request))\n\n        # Create the root factory\n        root = root_factory(request)\n        attrs['root'] = root\n\n        # We are about to traverse and find a context\n        traverser = adapters.queryAdapter(root, ITraverser)\n        if traverser is None:\n            traverser = ResourceTreeTraverser(root)\n        tdict = traverser(request)\n\n        context, view_name, subpath, traversed, vroot, vroot_path = (\n            tdict['context'],\n            tdict['view_name'],\n            tdict['subpath'],\n            tdict['traversed'],\n            tdict['virtual_root'],\n            tdict['virtual_root_path'],\n        )\n\n        attrs.update(tdict)\n\n        # Notify anyone listening that we have a context and traversal is\n        # complete\n        has_listeners and notify(ContextFound(request))\n\n        # find a view callable\n        context_iface = providedBy(context)\n        response = _call_view(\n            registry, request, context, context_iface, view_name\n        )\n\n        if response is None:\n            if self.debug_notfound:\n                msg = (\n                    'debug_notfound of url %s; path_info: %r, '\n                    'context: %r, view_name: %r, subpath: %r, '\n                    'traversed: %r, root: %r, vroot: %r, '\n                    'vroot_path: %r'\n                    % (\n                        request.url,\n                        request.path_info,\n                        context,\n                        view_name,\n                        subpath,\n                        traversed,\n                        root,\n                        vroot,\n                        vroot_path,\n                    )\n                )\n                logger and logger.debug(msg)\n            else:\n                msg = request.path_info\n            raise HTTPNotFound(msg)\n\n        return response\n\n    def invoke_subrequest(self, request, use_tweens=False):\n        \"\"\"Obtain a response object from the Pyramid application based on\n        information in the ``request`` object provided.  The ``request``\n        object must be an object that implements the Pyramid request\n        interface (such as a :class:`pyramid.request.Request` instance).  If\n        ``use_tweens`` is ``True``, the request will be sent to the\n        :term:`tween` in the tween stack closest to the request ingress.  If\n        ``use_tweens`` is ``False``, the request will be sent to the main\n        router handler, and no tweens will be invoked.\n\n        See the API for pyramid.request for complete documentation.\n        \"\"\"\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        with RequestContext(request):\n            return self.invoke_request(request, _use_tweens=use_tweens)\n\n    def request_context(self, environ):\n        \"\"\"\n        Create a new request context from a WSGI environ.\n\n        The request context is used to push/pop the threadlocals required\n        when processing the request. It also contains an initialized\n        :class:`pyramid.interfaces.IRequest` instance using the registered\n        :class:`pyramid.interfaces.IRequestFactory`. The context may be\n        used as a context manager to control the threadlocal lifecycle:\n\n        .. code-block:: python\n\n            with router.request_context(environ) as request:\n                ...\n\n        Alternatively, the context may be used without the ``with`` statement\n        by manually invoking its ``begin()`` and ``end()`` methods.\n\n        .. code-block:: python\n\n            ctx = router.request_context(environ)\n            request = ctx.begin()\n            try:\n                ...\n            finally:\n                ctx.end()\n\n        \"\"\"\n        request = self.request_factory(environ)\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        return RequestContext(request)\n\n    def invoke_request(self, request, _use_tweens=True):\n        \"\"\"\n        Execute a request through the request processing pipeline and\n        return the generated response.\n\n        \"\"\"\n        registry = self.registry\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n\n        if _use_tweens:\n            handle_request = self.handle_request\n        else:\n            handle_request = self.orig_handle_request\n\n        try:\n            response = handle_request(request)\n\n            if request.response_callbacks:\n                request._process_response_callbacks(response)\n\n            has_listeners and notify(NewResponse(request, response))\n\n            return response\n\n        finally:\n            self.finish_request(request)\n\n    def finish_request(self, request):\n        if request.finished_callbacks:\n            request._process_finished_callbacks()\n        request.__dict__.pop('context', None)  # Break potential ref cycle\n\n    def __call__(self, environ, start_response):\n        \"\"\"\n        Accept ``environ`` and ``start_response``; create a\n        :term:`request` and route the request to a :app:`Pyramid`\n        view based on introspection of :term:`view configuration`\n        within the application registry; call ``start_response`` and\n        return an iterable.\n        \"\"\"\n        response = self.execution_policy(environ, self)\n        return response(environ, start_response)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 30,
                                "end_lineno": 271,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                }
            ]
        },
        {
            "old_file_content": "import unittest\nfrom zope.interface import implementer\n\nfrom pyramid import testing\nfrom pyramid.interfaces import IResponse\n\n\nclass TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_call_request_has_finished_callbacks_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_has_finished_callbacks_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n\nclass DummyPredicate:\n    def __call__(self, info, request):\n        return True\n\n    def text(self):\n        return 'predicate'\n\n\nclass DummyContext:\n    pass\n\n\nclass DummyView:\n    def __init__(self, response, raise_exception=None):\n        self.response = response\n        self.raise_exception = raise_exception\n\n    def __call__(self, context, request):\n        self.context = context\n        self.request = request\n        if self.raise_exception is not None:\n            raise self.raise_exception\n        return self.response\n\n\nclass DummyRootFactory:\n    def __init__(self, root):\n        self.root = root\n\n    def __call__(self, environ):\n        return self.root\n\n\nclass DummyStartResponse:\n    status = ()\n    headers = ()\n\n    def __call__(self, status, headers):\n        self.status = status\n        self.headers = headers\n\n\n@implementer(IResponse)\nclass DummyResponse:\n    headerlist = ()\n    app_iter = ()\n    environ = None\n\n    def __init__(self, status='200 OK'):\n        self.status = status\n\n    def __call__(self, environ, start_response):\n        self.environ = environ\n        start_response(self.status, self.headerlist)\n        return self.app_iter\n\n\nclass DummyLogger:\n    def __init__(self):\n        self.messages = []\n\n    def info(self, msg):\n        self.messages.append(msg)\n\n    warn = info\n    debug = info\n\n\ndef exc_raised(exc, func, *arg, **kw):\n    try:\n        func(*arg, **kw)\n    except exc as e:\n        return e\n    else:\n        raise AssertionError('%s not raised' % exc)  # pragma: no cover\n",
            "new_file_content": "import unittest\nfrom zope.interface import implementer\n\nfrom pyramid import testing\nfrom pyramid.interfaces import IResponse\n\n\nclass TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n\nclass DummyPredicate:\n    def __call__(self, info, request):\n        return True\n\n    def text(self):\n        return 'predicate'\n\n\nclass DummyContext:\n    pass\n\n\nclass DummyView:\n    def __init__(self, response, raise_exception=None):\n        self.response = response\n        self.raise_exception = raise_exception\n\n    def __call__(self, context, request):\n        self.context = context\n        self.request = request\n        if self.raise_exception is not None:\n            raise self.raise_exception\n        return self.response\n\n\nclass DummyRootFactory:\n    def __init__(self, root):\n        self.root = root\n\n    def __call__(self, environ):\n        return self.root\n\n\nclass DummyStartResponse:\n    status = ()\n    headers = ()\n\n    def __call__(self, status, headers):\n        self.status = status\n        self.headers = headers\n\n\n@implementer(IResponse)\nclass DummyResponse:\n    headerlist = ()\n    app_iter = ()\n    environ = None\n\n    def __init__(self, status='200 OK'):\n        self.status = status\n\n    def __call__(self, environ, start_response):\n        self.environ = environ\n        start_response(self.status, self.headerlist)\n        return self.app_iter\n\n\nclass DummyLogger:\n    def __init__(self):\n        self.messages = []\n\n    def info(self, msg):\n        self.messages.append(msg)\n\n    warn = info\n    debug = info\n\n\ndef exc_raised(exc, func, *arg, **kw):\n    try:\n        func(*arg, **kw)\n    except exc as e:\n        return e\n    else:\n        raise AssertionError('%s not raised' % exc)  # pragma: no cover\n",
            "header": {
                "file": {
                    "path": "tests/test_router.py"
                },
                "misc_line": null
            },
            "index_line": {
                "old_commit_hash": "0f00ea531",
                "new_commit_hash": "857e8aea5",
                "mode": "100644"
            },
            "is_binary_file": false,
            "binary_line": null,
            "minus_file": {
                "path": "a/tests/test_router.py"
            },
            "plus_file": {
                "path": "b/tests/test_router.py"
            },
            "hunks": [
                {
                    "descriptor": {
                        "old_range": {
                            "start": 124,
                            "length": 6
                        },
                        "new_range": {
                            "start": 124,
                            "length": 19
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        klass = self._getTargetClass()",
                                "type": "context"
                            },
                            {
                                "content": "        return klass(self.registry)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def _mockFinishRequest(self, router):",
                                "type": "added"
                            },
                            {
                                "content": "        \"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This",
                                "type": "added"
                            },
                            {
                                "content": "        prevents :prop:`pyramid.request.Request.context` from being removed, so",
                                "type": "added"
                            },
                            {
                                "content": "        we can write assertions against it.",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        \"\"\"",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        def mock_finish_request(request):",
                                "type": "added"
                            },
                            {
                                "content": "            pass",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "        router.finish_request = mock_finish_request",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "added"
                            },
                            {
                                "content": "    def _makeEnviron(self, **extras):",
                                "type": "context"
                            },
                            {
                                "content": "        environ = {",
                                "type": "context"
                            },
                            {
                                "content": "            'wsgi.url_scheme': 'http',",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1685,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter._mockFinishRequest",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 127,
                            "end_lineno": 138,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 421,
                            "length": 6
                        },
                        "new_range": {
                            "start": 434,
                            "length": 7
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        )",
                                "type": "context"
                            },
                            {
                                "content": "        self._registerRootFactory(context)",
                                "type": "context"
                            },
                            {
                                "content": "        router = self._makeOne()",
                                "type": "context"
                            },
                            {
                                "content": "        self._mockFinishRequest(router)",
                                "type": "added"
                            },
                            {
                                "content": "        start_response = DummyStartResponse()",
                                "type": "context"
                            },
                            {
                                "content": "        result = router(environ, start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(result, ['Hello world'])",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_call_view_registered_nonspecific_default_path",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 423,
                            "end_lineno": 447,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1685,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 448,
                            "length": 6
                        },
                        "new_range": {
                            "start": 462,
                            "length": 7
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        environ = self._makeEnviron()",
                                "type": "context"
                            },
                            {
                                "content": "        self._registerView(view, 'foo', IViewClassifier, None, None)",
                                "type": "context"
                            },
                            {
                                "content": "        router = self._makeOne()",
                                "type": "context"
                            },
                            {
                                "content": "        self._mockFinishRequest(router)",
                                "type": "added"
                            },
                            {
                                "content": "        start_response = DummyStartResponse()",
                                "type": "context"
                            },
                            {
                                "content": "        result = router(environ, start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(result, ['Hello world'])",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_call_view_registered_nonspecific_nondefault_path_and_subpath",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 449,
                            "end_lineno": 475,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1685,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 477,
                            "length": 6
                        },
                        "new_range": {
                            "start": 492,
                            "length": 7
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        environ = self._makeEnviron()",
                                "type": "context"
                            },
                            {
                                "content": "        self._registerView(view, '', IViewClassifier, IRequest, IContext)",
                                "type": "context"
                            },
                            {
                                "content": "        router = self._makeOne()",
                                "type": "context"
                            },
                            {
                                "content": "        self._mockFinishRequest(router)",
                                "type": "added"
                            },
                            {
                                "content": "        start_response = DummyStartResponse()",
                                "type": "context"
                            },
                            {
                                "content": "        result = router(environ, start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(result, ['Hello world'])",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_call_view_registered_specific_success",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 477,
                            "end_lineno": 505,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1685,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 618,
                            "length": 7
                        },
                        "new_range": {
                            "start": 634,
                            "length": 7
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        router(environ, start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(response.called_back, True)",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_call_request_has_finished_callbacks_when_view_succeeds(self):",
                                "type": "deleted"
                            },
                            {
                                "content": "    def test_finish_request_when_view_succeeds(self):",
                                "type": "added"
                            },
                            {
                                "content": "        from zope.interface import Interface, directlyProvides",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        class IContext(Interface):",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_call_request_has_finished_callbacks_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_has_finished_callbacks_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1662,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_finish_request_when_view_succeeds",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 637,
                            "end_lineno": 664,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_call_request_has_finished_callbacks_when_view_succeeds",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_call_request_has_finished_callbacks_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_has_finished_callbacks_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 621,
                            "end_lineno": 646,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_call_request_has_finished_callbacks_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_has_finished_callbacks_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1662,
                                "parent": null
                            }
                        }
                    ]
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 636,
                            "length": 6
                        },
                        "new_range": {
                            "start": 652,
                            "length": 7
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "                request.environ['called_back'] = True",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "            request.add_finished_callback(callback)",
                                "type": "context"
                            },
                            {
                                "content": "            request.environ['request'] = request",
                                "type": "added"
                            },
                            {
                                "content": "            return response",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        environ = self._makeEnviron()",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1685,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_finish_request_when_view_succeeds",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 637,
                            "end_lineno": 664,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 644,
                            "length": 8
                        },
                        "new_range": {
                            "start": 661,
                            "length": 9
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        start_response = DummyStartResponse()",
                                "type": "context"
                            },
                            {
                                "content": "        router(environ, start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(environ['called_back'], True)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertFalse(hasattr(environ['request'], 'context'))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_call_request_has_finished_callbacks_when_view_raises(self):",
                                "type": "deleted"
                            },
                            {
                                "content": "    def test_finish_request_when_view_raises(self):",
                                "type": "added"
                            },
                            {
                                "content": "        from zope.interface import Interface, directlyProvides",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        class IContext(Interface):",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_call_request_has_finished_callbacks_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_has_finished_callbacks_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1662,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_finish_request_when_view_raises",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 666,
                            "end_lineno": 692,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_finish_request_when_view_succeeds",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 637,
                            "end_lineno": 664,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_call_request_has_finished_callbacks_when_view_raises",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_call_request_has_finished_callbacks_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_has_finished_callbacks_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 648,
                            "end_lineno": 672,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_call_request_has_finished_callbacks_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_has_finished_callbacks_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1662,
                                "parent": null
                            }
                        }
                    ]
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 662,
                            "length": 6
                        },
                        "new_range": {
                            "start": 680,
                            "length": 7
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "                request.environ['called_back'] = True",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "            request.add_finished_callback(callback)",
                                "type": "context"
                            },
                            {
                                "content": "            request.environ['request'] = request",
                                "type": "added"
                            },
                            {
                                "content": "            raise NotImplementedError",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "        environ = self._makeEnviron()",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1685,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_finish_request_when_view_raises",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 666,
                            "end_lineno": 692,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 670,
                            "length": 6
                        },
                        "new_range": {
                            "start": 689,
                            "length": 7
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        start_response = DummyStartResponse()",
                                "type": "context"
                            },
                            {
                                "content": "        exc_raised(NotImplementedError, router, environ, start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(environ['called_back'], True)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertFalse(hasattr(environ['request'], 'context'))",
                                "type": "added"
                            },
                            {
                                "content": "",
                                "type": "context"
                            },
                            {
                                "content": "    def test_call_request_factory_raises(self):",
                                "type": "context"
                            },
                            {
                                "content": "        # making sure finally doesnt barf when a request cannot be created",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1685,
                            "parent": null
                        }
                    ],
                    "added_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_finish_request_when_view_raises",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 666,
                            "end_lineno": 692,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        }
                    ],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 704,
                            "length": 6
                        },
                        "new_range": {
                            "start": 724,
                            "length": 7
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        context_found_events = self._registerEventListener(IContextFound)",
                                "type": "context"
                            },
                            {
                                "content": "        response_events = self._registerEventListener(INewResponse)",
                                "type": "context"
                            },
                            {
                                "content": "        router = self._makeOne()",
                                "type": "context"
                            },
                            {
                                "content": "        self._mockFinishRequest(router)",
                                "type": "added"
                            },
                            {
                                "content": "        start_response = DummyStartResponse()",
                                "type": "context"
                            },
                            {
                                "content": "        result = router(environ, start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(len(request_events), 1)",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_call_eventsends",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 706,
                            "end_lineno": 740,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1685,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 767,
                            "length": 6
                        },
                        "new_range": {
                            "start": 788,
                            "length": 7
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self._registerView(view, '', IViewClassifier, None, None)",
                                "type": "context"
                            },
                            {
                                "content": "        self._registerRootFactory(context)",
                                "type": "context"
                            },
                            {
                                "content": "        router = self._makeOne()",
                                "type": "context"
                            },
                            {
                                "content": "        self._mockFinishRequest(router)",
                                "type": "added"
                            },
                            {
                                "content": "        start_response = DummyStartResponse()",
                                "type": "context"
                            },
                            {
                                "content": "        result = router(environ, start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(result, ['Hello world'])",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_call_route_matches_and_has_factory",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 769,
                            "end_lineno": 814,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1685,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                },
                {
                    "descriptor": {
                        "old_range": {
                            "start": 841,
                            "length": 6
                        },
                        "new_range": {
                            "start": 863,
                            "length": 7
                        },
                        "section": "class TestRouter(unittest.TestCase):"
                    },
                    "line_group": {
                        "all_lines": [
                            {
                                "content": "        self._registerView(view, '', IViewClassifier, None, None)",
                                "type": "context"
                            },
                            {
                                "content": "        self._registerRootFactory(context)",
                                "type": "context"
                            },
                            {
                                "content": "        router = self._makeOne()",
                                "type": "context"
                            },
                            {
                                "content": "        self._mockFinishRequest(router)",
                                "type": "added"
                            },
                            {
                                "content": "        start_response = DummyStartResponse()",
                                "type": "context"
                            },
                            {
                                "content": "        result = router(environ, start_response)",
                                "type": "context"
                            },
                            {
                                "content": "        self.assertEqual(result, ['Hello world'])",
                                "type": "context"
                            },
                            {
                                "content": "",
                                "type": "context"
                            }
                        ]
                    },
                    "modified_entities": [
                        {
                            "file_name": "tests/test_router.py",
                            "type": "method",
                            "name": "TestRouter.test_call_route_matches_doesnt_overwrite_subscriber_iface",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 837,
                            "end_lineno": 880,
                            "parent": {
                                "file_name": "tests/test_router.py",
                                "type": "class",
                                "name": "TestRouter",
                                "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                                "ast_type_str": "ClassDef",
                                "start_lineno": 8,
                                "end_lineno": 1685,
                                "parent": null
                            }
                        },
                        {
                            "file_name": "tests/test_router.py",
                            "type": "class",
                            "name": "TestRouter",
                            "content": "class TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)",
                            "ast_type_str": "ClassDef",
                            "start_lineno": 8,
                            "end_lineno": 1685,
                            "parent": null
                        }
                    ],
                    "added_entities": [],
                    "deleted_entities": []
                }
            ]
        }
    ],
    "old_commit_hash": "68c84ae5aa2898251a07455e958fd0a11926d114^",
    "new_commit_hash": "68c84ae5aa2898251a07455e958fd0a11926d114",
    "commit_message": "Merge pull request #3649 from luhn/context-break-cycles\n\nBreak reference cycle between request and context.",
    "commit_date": "2021-01-20T00:45:33-06:00",
    "metadata": {}
}
{
    "repo_name": "pyramid",
    "new_commit_hash": "68c84ae5aa2898251a07455e958fd0a11926d114",
    "test_file_codes": [
        "import unittest\nfrom zope.interface import implementer\n\nfrom pyramid import testing\nfrom pyramid.interfaces import IResponse\n\n\nclass TestRouter(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n        self.registry = self.config.registry\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def _registerRouteRequest(self, name):\n        from pyramid.interfaces import IRouteRequest\n        from pyramid.request import route_request_iface\n\n        iface = route_request_iface(name)\n        self.registry.registerUtility(iface, IRouteRequest, name=name)\n        return iface\n\n    def _connectRoute(self, name, path, factory=None):\n        from pyramid.interfaces import IRoutesMapper\n        from pyramid.urldispatch import RoutesMapper\n\n        mapper = self.registry.queryUtility(IRoutesMapper)\n        if mapper is None:\n            mapper = RoutesMapper()\n            self.registry.registerUtility(mapper, IRoutesMapper)\n        return mapper.connect(name, path, factory)\n\n    def _registerLogger(self):\n        from pyramid.interfaces import IDebugLogger\n\n        logger = DummyLogger()\n        self.registry.registerUtility(logger, IDebugLogger)\n        return logger\n\n    def _registerSettings(self, **kw):\n        settings = {\n            'debug_authorization': False,\n            'debug_notfound': False,\n            'debug_routematch': False,\n        }\n        settings.update(kw)\n        self.registry.settings = settings\n\n    def _registerTraverserFactory(\n        self,\n        context,\n        view_name='',\n        subpath=None,\n        traversed=None,\n        virtual_root=None,\n        virtual_root_path=None,\n        raise_error=None,\n        **kw\n    ):\n        from pyramid.interfaces import ITraverser\n\n        if virtual_root is None:\n            virtual_root = context\n        if subpath is None:\n            subpath = []\n        if traversed is None:\n            traversed = []\n        if virtual_root_path is None:\n            virtual_root_path = []\n\n        class DummyTraverserFactory:\n            def __init__(self, root):\n                self.root = root\n\n            def __call__(self, request):\n                if raise_error:\n                    raise raise_error\n                values = {\n                    'root': self.root,\n                    'context': context,\n                    'view_name': view_name,\n                    'subpath': subpath,\n                    'traversed': traversed,\n                    'virtual_root': virtual_root,\n                    'virtual_root_path': virtual_root_path,\n                }\n                kw.update(values)\n                return kw\n\n        self.registry.registerAdapter(\n            DummyTraverserFactory, (None,), ITraverser, name=''\n        )\n\n    def _registerView(self, app, name, classifier, req_iface, ctx_iface):\n        from pyramid.interfaces import IView\n\n        self.registry.registerAdapter(\n            app, (classifier, req_iface, ctx_iface), IView, name\n        )\n\n    def _registerEventListener(self, iface):\n        L = []\n\n        def listener(event):\n            L.append(event)\n\n        self.registry.registerHandler(listener, (iface,))\n        return L\n\n    def _registerRootFactory(self, val):\n        rootfactory = DummyRootFactory(val)\n        from pyramid.interfaces import IRootFactory\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        return rootfactory\n\n    def _getTargetClass(self):\n        from pyramid.router import Router\n\n        return Router\n\n    def _makeOne(self):\n        klass = self._getTargetClass()\n        return klass(self.registry)\n\n    def _mockFinishRequest(self, router):\n        \"\"\"\n        Mock :meth:`pyramid.router.Router.finish_request` to be a no-op.  This\n        prevents :prop:`pyramid.request.Request.context` from being removed, so\n        we can write assertions against it.\n\n        \"\"\"\n\n        def mock_finish_request(request):\n            pass\n\n        router.finish_request = mock_finish_request\n\n    def _makeEnviron(self, **extras):\n        environ = {\n            'wsgi.url_scheme': 'http',\n            'SERVER_NAME': 'localhost',\n            'SERVER_PORT': '8080',\n            'REQUEST_METHOD': 'GET',\n            'PATH_INFO': '/',\n        }\n        environ.update(extras)\n        return environ\n\n    def test_ctor_registry_has_no_settings(self):\n        self.registry.settings = None\n        router = self._makeOne()\n        self.assertEqual(router.debug_notfound, False)\n        self.assertEqual(router.debug_routematch, False)\n        self.assertFalse('debug_notfound' in router.__dict__)\n        self.assertFalse('debug_routematch' in router.__dict__)\n\n    def test_root_policy(self):\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        rootfactory = self._registerRootFactory('abc')\n        router = self._makeOne()\n        self.assertEqual(router.root_policy, rootfactory)\n\n    def test_request_factory(self):\n        from pyramid.interfaces import IRequestFactory\n\n        class DummyRequestFactory:\n            pass\n\n        self.registry.registerUtility(DummyRequestFactory, IRequestFactory)\n        router = self._makeOne()\n        self.assertEqual(router.request_factory, DummyRequestFactory)\n\n    def test_tween_factories(self):\n        from pyramid.config.tweens import Tweens\n        from pyramid.interfaces import IResponse, ITweens, IViewClassifier\n        from pyramid.response import Response\n\n        tweens = Tweens()\n        self.registry.registerUtility(tweens, ITweens)\n        L = []\n\n        def tween_factory1(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'].append('one')\n                return handler(request)\n\n            wrapper.name = 'one'\n            wrapper.child = handler\n            return wrapper\n\n        def tween_factory2(handler, registry):\n            L.append((handler, registry))\n\n            def wrapper(request):\n                request.environ['handled'] = ['two']\n                return handler(request)\n\n            wrapper.name = 'two'\n            wrapper.child = handler\n            return wrapper\n\n        tweens.add_implicit('one', tween_factory1)\n        tweens.add_implicit('two', tween_factory2)\n        router = self._makeOne()\n        self.assertEqual(router.handle_request.name, 'two')\n        self.assertEqual(router.handle_request.child.name, 'one')\n        self.assertEqual(\n            router.handle_request.child.child.__name__, 'handle_request'\n        )\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n        self.assertEqual(environ['handled'], ['two', 'one'])\n\n    def test_call_traverser_default(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_traverser_raises_notfound_class(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPNotFound)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_traverser_raises_notfound_instance(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPNotFound('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_traverser_raises_forbidden_class(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=HTTPForbidden)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPForbidden, router, environ, start_response)\n\n    def test_traverser_raises_forbidden_instance(self):\n        from pyramid.httpexceptions import HTTPForbidden\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, raise_error=HTTPForbidden('foo')\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('foo' in why.args[0], why)\n\n    def test_call_no_view_registered_no_isettings(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_false(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        logger = self._registerLogger()\n        self._registerSettings(debug_notfound=False)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('/' in why.args[0], why)\n        self.assertFalse('debug_notfound' in why.args[0])\n        self.assertEqual(len(logger.messages), 0)\n\n    def test_call_no_view_registered_debug_notfound_true(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        self._registerSettings(debug_notfound=True)\n        logger = self._registerLogger()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue(\n            \"debug_notfound of url http://localhost:8080/; \" in why.args[0]\n        )\n        self.assertTrue(\"view_name: '', subpath: []\" in why.args[0])\n        self.assertTrue('http://localhost:8080' in why.args[0], why)\n\n        self.assertEqual(len(logger.messages), 1)\n        message = logger.messages[0]\n        self.assertTrue('of url http://localhost:8080' in message)\n        self.assertTrue(\"path_info: \" in message)\n        self.assertTrue('DummyContext' in message)\n        self.assertTrue(\"view_name: ''\" in message)\n        self.assertTrue(\"subpath: []\" in message)\n\n    def test_call_view_returns_non_iresponse(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_view_returns_adapted_response(self):\n        from pyramid.interfaces import IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n        view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n        self.assertEqual(start_response.status, '200 OK')\n\n    def test_call_with_request_extensions(self):\n        from pyramid.interfaces import (\n            IRequest,\n            IRequestExtensions,\n            IViewClassifier,\n        )\n        from pyramid.request import Request\n        from pyramid.util import InstancePropertyHelper\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n\n        class Extensions:\n            def __init__(self):\n                self.methods = {}\n                self.descriptors = {}\n\n        extensions = Extensions()\n        ext_method = lambda r: 'bar'\n        name, fn = InstancePropertyHelper.make_property(ext_method, name='foo')\n        extensions.descriptors[name] = fn\n        request = Request.blank('/')\n        request.request_iface = IRequest\n        request.registry = self.registry\n\n        def request_factory(environ):\n            return request\n\n        self.registry.registerUtility(extensions, IRequestExtensions)\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        router = self._makeOne()\n        router.request_factory = request_factory\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(view.request.foo, 'bar')\n\n    def test_call_view_registered_nonspecific_default_path(self):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, None, None\n        )\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_nonspecific_nondefault_path_and_subpath(\n        self,\n    ):\n        from pyramid.interfaces import IViewClassifier\n\n        context = DummyContext()\n        self._registerTraverserFactory(\n            context, view_name='foo', subpath=['bar'], traversed=['context']\n        )\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, 'foo', IViewClassifier, None, None)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, 'foo')\n        self.assertEqual(request.subpath, ['bar'])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_success(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context)\n        self._registerRootFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, context)\n\n    def test_call_view_registered_specific_fail(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class INotContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest\n\n        context = DummyContext()\n        directlyProvides(context, INotContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n    def test_call_view_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(\n            response, raise_exception=HTTPForbidden(\"unauthorized\")\n        )\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertEqual(why.args[0], 'unauthorized')\n\n    def test_call_view_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=HTTPNotFound(\"notfound\"))\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertEqual(why.args[0], 'notfound')\n\n    def test_call_view_raises_response_cleared(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IExceptionViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            request.response.a = 1\n            raise KeyError\n\n        def exc_view(context, request):\n            self.assertFalse(hasattr(request.response, 'a'))\n            request.response.body = b'OK'\n            return request.response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exc_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        itera = router(environ, start_response)\n        self.assertEqual(itera, [b'OK'])\n\n    def test_call_request_has_response_callbacks(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request, response):\n                response.called_back = True\n\n            request.add_response_callback(callback)\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(response.called_back, True)\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n\n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n\n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n        self.assertFalse(hasattr(environ['request'], 'context'))\n\n    def test_call_request_factory_raises(self):\n        # making sure finally doesnt barf when a request cannot be created\n        environ = self._makeEnviron()\n        router = self._makeOne()\n\n        def dummy_request_factory(environ):\n            raise NotImplementedError\n\n        router.request_factory = dummy_request_factory\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n\n    def test_call_eventsends(self):\n        from pyramid.interfaces import (\n            IBeforeTraversal,\n            IContextFound,\n            INewRequest,\n            INewResponse,\n            IViewClassifier,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, None, None)\n        request_events = self._registerEventListener(INewRequest)\n        beforetraversal_events = self._registerEventListener(IBeforeTraversal)\n        context_found_events = self._registerEventListener(IContextFound)\n        response_events = self._registerEventListener(INewResponse)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(len(request_events), 1)\n        self.assertEqual(request_events[0].request.environ, environ)\n        self.assertEqual(len(beforetraversal_events), 1)\n        self.assertEqual(beforetraversal_events[0].request.environ, environ)\n        self.assertEqual(len(context_found_events), 1)\n        self.assertEqual(context_found_events[0].request.environ, environ)\n        self.assertEqual(context_found_events[0].request.context, context)\n        self.assertEqual(len(response_events), 1)\n        self.assertEqual(response_events[0].response, response)\n        self.assertEqual(response_events[0].request.context, context)\n        self.assertEqual(result, response.app_iter)\n\n    def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            INewRequest,\n            IRequest,\n        )\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron()\n\n        def listener(event):\n            raise KeyError\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(\n            exception_view, '', IExceptionViewClassifier, IRequest, KeyError\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, exception_response.app_iter)\n\n    def test_call_route_matches_and_has_factory(self):\n        from pyramid.interfaces import IViewClassifier\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        root = object()\n\n        def factory(request):\n            return root\n\n        route = self._connectRoute('foo', 'archives/:action/:article', factory)\n        route.predicates = [DummyPredicate()]\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertEqual(len(logger.messages), 1)\n        self.assertTrue(\n            logger.messages[0].startswith(\n                \"route matched for url http://localhost:8080\"\n                \"/archives/action1/article1; \"\n                \"route_name: 'foo', \"\n                \"path_info: \"\n            )\n        )\n        self.assertTrue(\"predicates: 'predicate'\" in logger.messages[0])\n\n    def test_call_route_match_miss_debug_routematch(self):\n        from pyramid.httpexceptions import HTTPNotFound\n\n        logger = self._registerLogger()\n        self._registerSettings(debug_routematch=True)\n        self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article')\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        environ = self._makeEnviron(PATH_INFO='/wontmatch')\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(HTTPNotFound, router, environ, start_response)\n\n        self.assertEqual(len(logger.messages), 1)\n        self.assertEqual(\n            logger.messages[0],\n            'no route matched for url http://localhost:8080/wontmatch',\n        )\n\n    def test_call_route_matches_doesnt_overwrite_subscriber_iface(self):\n        from zope.interface import Interface, alsoProvides\n\n        from pyramid.interfaces import INewRequest, IViewClassifier\n\n        self._registerRouteRequest('foo')\n\n        class IFoo(Interface):\n            pass\n\n        def listener(event):\n            alsoProvides(event.request, IFoo)\n\n        self.registry.registerHandler(listener, (INewRequest,))\n        root = object()\n\n        def factory(request):\n            return root\n\n        self._connectRoute('foo', 'archives/:action/:article', factory)\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        response = DummyResponse()\n        response.app_iter = ['Hello world']\n        view = DummyView(response)\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        self._registerView(view, '', IViewClassifier, None, None)\n        self._registerRootFactory(context)\n        router = self._makeOne()\n        self._mockFinishRequest(router)\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['Hello world'])\n        self.assertEqual(start_response.headers, ())\n        self.assertEqual(start_response.status, '200 OK')\n        request = view.request\n        self.assertEqual(request.view_name, '')\n        self.assertEqual(request.subpath, [])\n        self.assertEqual(request.context, context)\n        self.assertEqual(request.root, root)\n        matchdict = {'action': 'action1', 'article': 'article1'}\n        self.assertEqual(request.matchdict, matchdict)\n        self.assertEqual(request.matched_route.name, 'foo')\n        self.assertTrue(IFoo.providedBy(request))\n\n    def test_root_factory_raises_notfound(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPNotFound('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPNotFound, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_raises_forbidden(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise HTTPForbidden('from root factory')\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        why = exc_raised(HTTPForbidden, router, environ, start_response)\n        self.assertTrue('from root factory' in why.args[0])\n\n    def test_root_factory_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        from pyramid.interfaces import IRootFactory\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n\n        class IContext(Interface):\n            pass\n\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_traverser_exception_propagating(self):\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_exception_propagating(self):\n        from zope.interface import Interface, directlyProvides\n\n        class IContext(Interface):\n            pass\n\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRequestFactory,\n            IViewClassifier,\n        )\n\n        def rfactory(environ):\n            return request\n\n        self.registry.registerUtility(rfactory, IRequestFactory)\n        from pyramid.request import Request\n\n        request = Request.blank('/')\n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse()\n        response.app_iter = ['OK']\n        error = RuntimeError()\n        view = DummyView(response, raise_exception=error)\n        environ = self._makeEnviron()\n\n        def exception_view(context, request):\n            self.assertEqual(request.exc_info[0], RuntimeError)\n            return response\n\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, ['OK'])\n        # exc_info and exception should still be around on the request after\n        # the excview tween has run (see\n        # https://github.com/Pylons/pyramid/issues/1223)\n        self.assertEqual(request.exception, error)\n        self.assertEqual(request.exc_info[:2], (RuntimeError, error))\n\n    def test_call_view_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        def exception_view(context, request):\n            self.assertEqual(request.exception.__class__, RuntimeError)\n            return exception_response\n\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SuperException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_view_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=SubException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=MyException)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_root_factory_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IRootFactory,\n        )\n\n        def rootfactory(request):\n            raise RuntimeError()\n\n        self.registry.registerUtility(rootfactory, IRootFactory)\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [\"Hello, world\"])\n\n    def test_traverser_raises_exception_view(self):\n        from pyramid.interfaces import IExceptionViewClassifier, IRequest\n\n        environ = self._makeEnviron()\n        context = DummyContext()\n        self._registerTraverserFactory(context, raise_error=RuntimeError())\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(exception_response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_exception_view_returns_non_iresponse(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        environ = self._makeEnviron()\n        response = DummyResponse()\n        view = DummyView(response, raise_exception=RuntimeError)\n\n        self._registerView(\n            self.config.derive_view(view), '', IViewClassifier, IRequest, None\n        )\n        exception_view = DummyView(None)\n        self._registerView(\n            self.config.derive_view(exception_view),\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(ValueError, router, environ, start_response)\n\n    def test_call_route_raises_route_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_view_raises_exception_route_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_route_raises_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_super_exception_sub_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SuperException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SubException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(SuperException, router, environ, start_response)\n\n    def test_call_route_raises_sub_exception_super_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class SuperException(Exception):\n            pass\n\n        class SubException(SuperException):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=SubException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            SuperException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, world\"])\n\n    def test_call_route_raises_exception_another_exception_view(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class MyException(Exception):\n            pass\n\n        class AnotherException(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=MyException)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            AnotherException,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(MyException, router, environ, start_response)\n\n    def test_call_route_raises_exception_view_specializing(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            IRequest,\n            RuntimeError,\n        )\n        response_spec = DummyResponse()\n        response_spec.app_iter = [\"Hello, special world\"]\n        exception_view_spec = DummyView(response_spec)\n        self._registerView(\n            exception_view_spec,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        result = router(environ, start_response)\n        self.assertEqual(result, [\"Hello, special world\"])\n\n    def test_call_route_raises_exception_view_another_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        another_req_iface = self._registerRouteRequest('bar')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=RuntimeError)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view = DummyView(response)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            another_req_iface,\n            RuntimeError,\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_exception_view_route(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        req_iface = self._registerRouteRequest('foo')\n        response = DummyResponse()\n        exception_response = DummyResponse()\n        exception_response.app_iter = [\"Hello, world\"]\n        view = DummyView(response, raise_exception=RuntimeError)\n        exception_view = DummyView(exception_response)\n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        self._registerView(\n            exception_view,\n            '',\n            IExceptionViewClassifier,\n            req_iface,\n            RuntimeError,\n        )\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(RuntimeError, router, environ, start_response)\n\n    def test_call_view_raises_predicate_mismatch(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, None)\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_call_view_predicate_mismatch_doesnt_hide_views(self):\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class BaseContext:\n            pass\n\n        class DummyContext(BaseContext):\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            BaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_multiple_predicate_mismatches_dont_hide_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IResponse, IViewClassifier\n        from pyramid.response import Response\n\n        class IBaseContext(Interface):\n            pass\n\n        class IContext(IBaseContext):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view1, '', IViewClassifier, IRequest, DummyContext)\n        view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view2, '', IViewClassifier, IRequest, IContext)\n        good_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(good_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IBaseContext,\n        )\n        router = self._makeOne()\n\n        def make_response(s):\n            return Response(s)\n\n        router.registry.registerAdapter(make_response, (str,), IResponse)\n        environ = self._makeEnviron()\n        start_response = DummyStartResponse()\n        app_iter = router(environ, start_response)\n        self.assertEqual(app_iter, [b'abc'])\n\n    def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self):\n        from zope.interface import Interface, implementer\n\n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.interfaces import IRequest, IViewClassifier\n\n        class IContext(Interface):\n            pass\n\n        class IOtherContext(Interface):\n            pass\n\n        @implementer(IContext)\n        class DummyContext:\n            pass\n\n        context = DummyContext()\n        self._registerTraverserFactory(context)\n        view = DummyView(DummyResponse(), raise_exception=PredicateMismatch)\n        self._registerView(view, '', IViewClassifier, IRequest, DummyContext)\n        please_dont_call_me_view = DummyView('abc')\n        self._registerView(\n            self.config.derive_view(please_dont_call_me_view),\n            '',\n            IViewClassifier,\n            IRequest,\n            IOtherContext,\n        )\n        router = self._makeOne()\n        environ = self._makeEnviron()\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        self.assertRaises(PredicateMismatch, router, environ, start_response)\n\n    def test_custom_execution_policy(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n\n        registry = self.config.registry\n\n        def dummy_policy(environ, router):\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n\n    def test_execution_policy_bubbles_exception(self):\n        from pyramid.interfaces import (\n            IExceptionViewClassifier,\n            IRequest,\n            IViewClassifier,\n        )\n\n        class Exception1(Exception):\n            pass\n\n        class Exception2(Exception):\n            pass\n\n        req_iface = self._registerRouteRequest('foo')\n        self._connectRoute('foo', 'archives/:action/:article', None)\n        view = DummyView(DummyResponse(), raise_exception=Exception1)\n        self._registerView(view, '', IViewClassifier, req_iface, None)\n        exception_view1 = DummyView(\n            DummyResponse(), raise_exception=Exception2\n        )\n        self._registerView(\n            exception_view1, '', IExceptionViewClassifier, IRequest, Exception1\n        )\n        response = DummyResponse()\n        response.app_iter = [\"Hello, world\"]\n        exception_view2 = DummyView(response)\n        self._registerView(\n            exception_view2, '', IExceptionViewClassifier, IRequest, Exception2\n        )\n        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')\n        start_response = DummyStartResponse()\n        router = self._makeOne()\n        self.assertRaises(Exception2, lambda: router(environ, start_response))\n\n    def test_request_context_with_statement(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            with router.request_context(environ):\n                result.append(get_current_request())\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n    def test_request_context_manually(self):\n        from pyramid.interfaces import IExecutionPolicy\n        from pyramid.request import Request\n        from pyramid.response import Response\n        from pyramid.threadlocal import get_current_request\n\n        registry = self.config.registry\n        result = []\n\n        def dummy_policy(environ, router):\n            ctx = router.request_context(environ)\n            ctx.begin()\n            result.append(get_current_request())\n            ctx.end()\n            result.append(get_current_request())\n            return Response(status=200, body=b'foo')\n\n        registry.registerUtility(dummy_policy, IExecutionPolicy)\n        router = self._makeOne()\n        resp = Request.blank('/test_path').get_response(router)\n        self.assertEqual(resp.status_code, 200)\n        self.assertEqual(resp.body, b'foo')\n        self.assertEqual(result[0].path_info, '/test_path')\n        self.assertEqual(result[1], None)\n\n\nclass DummyPredicate:\n    def __call__(self, info, request):\n        return True\n\n    def text(self):\n        return 'predicate'\n\n\nclass DummyContext:\n    pass\n\n\nclass DummyView:\n    def __init__(self, response, raise_exception=None):\n        self.response = response\n        self.raise_exception = raise_exception\n\n    def __call__(self, context, request):\n        self.context = context\n        self.request = request\n        if self.raise_exception is not None:\n            raise self.raise_exception\n        return self.response\n\n\nclass DummyRootFactory:\n    def __init__(self, root):\n        self.root = root\n\n    def __call__(self, environ):\n        return self.root\n\n\nclass DummyStartResponse:\n    status = ()\n    headers = ()\n\n    def __call__(self, status, headers):\n        self.status = status\n        self.headers = headers\n\n\n@implementer(IResponse)\nclass DummyResponse:\n    headerlist = ()\n    app_iter = ()\n    environ = None\n\n    def __init__(self, status='200 OK'):\n        self.status = status\n\n    def __call__(self, environ, start_response):\n        self.environ = environ\n        start_response(self.status, self.headerlist)\n        return self.app_iter\n\n\nclass DummyLogger:\n    def __init__(self):\n        self.messages = []\n\n    def info(self, msg):\n        self.messages.append(msg)\n\n    warn = info\n    debug = info\n\n\ndef exc_raised(exc, func, *arg, **kw):\n    try:\n        func(*arg, **kw)\n    except exc as e:\n        return e\n    else:\n        raise AssertionError('%s not raised' % exc)  # pragma: no cover\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 11 packages in 853ms\nPrepared 1 package in 937ms\nInstalled 11 packages in 13ms\n + hupper==1.12.1\n + pastedeploy==3.1.0\n + plaster==1.1.2\n + plaster-pastedeploy==1.0.1\n + pyramid==2.0b0 (from file:///home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114)\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 26 packages in 50ms\nInstalled 15 packages in 6ms\n + beautifulsoup4==4.12.3\n + coverage==7.6.1\n + exceptiongroup==1.2.2\n + iniconfig==2.0.0\n + packaging==24.2\n + pluggy==1.5.0\n + pytest==8.3.4\n + pytest-cov==5.0.0\n + soupsieve==2.6\n + tomli==2.2.1\n + waitress==3.0.0\n + webtest==3.0.1\n + zope-component==6.0\n + zope-event==5.0\n + zope-hookable==7.0\nResolved 16 packages in 6ms\nInstalled 10 packages in 7ms\n + cachetools==5.5.0\n + chardet==5.2.0\n + colorama==0.4.6\n + distlib==0.3.9\n + filelock==3.16.1\n + platformdirs==4.3.6\n + pyproject-api==1.8.0\n + tox==4.23.2\n + typing-extensions==4.12.2\n + virtualenv==20.29.0\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_68c84ae5aa2898251a07455e958fd0a11926d114\nconfigfile: setup.cfg\nplugins: cov-5.0.0\ncollected 885 items\n\nr2e_tests/test_1.py .................................................... [  5%]\n........                                                                 [  6%]\nr2e_tests/test_config/test_actions.py .................................. [ 10%]\n............                                                             [ 11%]\nr2e_tests/test_config/test_adapters.py .FF..............F...             [ 14%]\nr2e_tests/test_config/test_assets.py ....F.F...F...FF.FF................ [ 18%]\n.....................................F.F................................ [ 26%]\n                                                                         [ 26%]\nr2e_tests/test_config/test_factories.py ..........F.F..F.F               [ 28%]\nr2e_tests/test_config/test_i18n.py FFFF..FF.FFF.F                        [ 30%]\nr2e_tests/test_config/test_init.py .............................F..F.... [ 34%]\n....F......F...................F................F..F.FF...FFF...         [ 41%]\nr2e_tests/test_config/test_predicates.py ............................... [ 44%]\n........                                                                 [ 45%]\nr2e_tests/test_config/test_rendering.py ...                              [ 46%]\nr2e_tests/test_config/test_routes.py .............F.................     [ 49%]\nr2e_tests/test_config/test_security.py ..............                    [ 51%]\nr2e_tests/test_config/test_settings.py ........................          [ 54%]\nr2e_tests/test_config/test_testing.py ....F.......                       [ 55%]\nr2e_tests/test_config/test_tweens.py F.........F..F...................   [ 59%]\nr2e_tests/test_config/test_views.py ..........F.........F............F.. [ 63%]\nF.........F....................F....................F................... [ 71%]\n..............................FF.....FFF................................ [ 79%]\n.................................................................F...... [ 87%]\n.F.                                                                      [ 87%]\nr2e_tests/test_scripts/test_common.py ..                                 [ 88%]\nr2e_tests/test_scripts/test_pdistreport.py ..                            [ 88%]\nr2e_tests/test_scripts/test_prequest.py ...................              [ 90%]\nr2e_tests/test_scripts/test_proutes.py ...F.......FFFF.F.FF.F..F..FF.    [ 93%]\nr2e_tests/test_scripts/test_pserve.py .F.......                          [ 94%]\nr2e_tests/test_scripts/test_pshell.py .................                  [ 96%]\nr2e_tests/test_scripts/test_ptweens.py .....                             [ 97%]\nr2e_tests/test_scripts/test_pviews.py ..........FFFF..FFFFFF.            [100%]\n\n=================================== FAILURES ===================================\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    \n        config = self._makeOne(autocommit=True)\n        config.add_resource_url_adapter(\n            'tests.test_config.test_adapters.DummyResourceURL',\n            'tests.test_config.test_adapters.DummyIface',\n        )\n        iface = DummyIface()\n>       adapter = config.registry.getMultiAdapter((iface, iface), IResourceURL)\n\nr2e_tests/test_config/test_adapters.py:325: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <Registry r2e_tests.test_config>\nobjects = (<r2e_tests.test_config.test_adapters.DummyIface object at 0x782137cdfac0>, <r2e_tests.test_config.test_adapters.DummyIface object at 0x782137cdfac0>)\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 0x782137cdfac0>, <r2e_tests.test_config.test_adapters.DummyIface object at 0x782137cdfac0>), <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(\n            intr.discriminator, ('resource url adapter', DummyIface)\n        )\n        self.assertEqual(intr.category_name, 'resource url adapters')\n>       self.assertEqual(\n            intr.title,\n            \"resource url adapter for resource iface \"\n            \"<class 'tests.test_config.test_adapters.DummyIface'>\",\n        )\nE       AssertionError: \"reso[30 chars]iface <class 'r2e_tests.test_config.test_adapters.DummyIface'>\" != \"reso[30 chars]iface <class '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 'tests.test_config.test_adapters.DummyIface'>\n\nr2e_tests/test_config/test_adapters.py:371: 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    \n        config = self._makeOne(autocommit=True)\n        config.add_traverser(\n            'tests.test_config.test_adapters.DummyTraverser',\n            'tests.test_config.test_adapters.DummyIface',\n        )\n        iface = DummyIface()\n>       traverser = config.registry.getAdapter(iface, ITraverser)\n\nr2e_tests/test_config/test_adapters.py:279: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <Registry r2e_tests.test_config>\nobject = <r2e_tests.test_config.test_adapters.DummyIface object at 0x782137986f40>\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 0x782137986f40>, <InterfaceClass pyramid.interfaces.ITraverser>, '')\n\n.venv/lib/python3.8/site-packages/zope/interface/registry.py:368: ComponentLookupError\n___ TestAssetsConfiguratorMixin.test_override_asset_directory_with_directory ___\n\nself = <r2e_tests.test_config.test_assets.TestAssetsConfiguratorMixin testMethod=test_override_asset_directory_with_directory>\n\n    def test_override_asset_directory_with_directory(self):\n        from pyramid.config.assets import PackageAssetSource\n    \n        config = self._makeOne(autocommit=True)\n        override = DummyUnderOverride()\n        config.override_asset(\n            'tests.test_config.pkgs.asset:templates/',\n            'tests.test_config.pkgs.asset.subpackage:templates/',\n            _override=override,\n        )\n        from tests.test_config.pkgs import asset\n        from tests.test_config.pkgs.asset import subpackage\n    \n        self.assertEqual(override.package, asset)\n        self.assertEqual(override.path, 'templates/')\n        source = override.source\n        self.assertTrue(isinstance(source, PackageAssetSource))\n        self.assertEqual(source.package, subpackage)\n        self.assertEqual(source.prefix, 'templates/')\n    \n        resource_name = 'bar.pt'\n        expected = os.path.join(\n            here, 'pkgs', 'asset', 'subpackage', 'templates', 'bar.pt'\n        )\n>       self.assertEqual(override.source.get_filename(resource_name), expected)\nE       AssertionError: '/hom[90 chars]d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt' != '/hom[90 chars]d114/r2e_tests/test_config/pkgs/asset/subpacka[15 chars]r.pt'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:132: AssertionError\n____ TestAssetsConfiguratorMixin.test_override_asset_directory_with_package ____\n\nself = <r2e_tests.test_config.test_assets.TestAssetsConfiguratorMixin testMethod=test_override_asset_directory_with_package>\n\n    def test_override_asset_directory_with_package(self):\n        from pyramid.config.assets import PackageAssetSource\n    \n        config = self._makeOne(autocommit=True)\n        override = DummyUnderOverride()\n        config.override_asset(\n            'tests.test_config.pkgs.asset:templates/',\n            'tests.test_config.pkgs.asset.subpackage',\n            _override=override,\n        )\n        from tests.test_config.pkgs import asset\n        from tests.test_config.pkgs.asset import subpackage\n    \n        self.assertEqual(override.package, asset)\n        self.assertEqual(override.path, 'templates/')\n        source = override.source\n        self.assertTrue(isinstance(source, PackageAssetSource))\n        self.assertEqual(source.package, subpackage)\n        self.assertEqual(source.prefix, '')\n    \n        resource_name = 'templates/bar.pt'\n        expected = os.path.join(\n            here, 'pkgs', 'asset', 'subpackage', 'templates', 'bar.pt'\n        )\n>       self.assertEqual(override.source.get_filename(resource_name), expected)\nE       AssertionError: '/hom[90 chars]d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt' != '/hom[90 chars]d114/r2e_tests/test_config/pkgs/asset/subpacka[15 chars]r.pt'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:158: AssertionError\n________ TestAssetsConfiguratorMixin.test_override_asset_file_with_file ________\n\nself = <r2e_tests.test_config.test_assets.TestAssetsConfiguratorMixin testMethod=test_override_asset_file_with_file>\n\n    def test_override_asset_file_with_file(self):\n        from pyramid.config.assets import PackageAssetSource\n    \n        config = self._makeOne(autocommit=True)\n        override = DummyUnderOverride()\n        config.override_asset(\n            'tests.test_config.pkgs.asset:templates/foo.pt',\n            'tests.test_config.pkgs.asset.subpackage:templates/bar.pt',\n            _override=override,\n        )\n        from tests.test_config.pkgs import asset\n        from tests.test_config.pkgs.asset import subpackage\n    \n        self.assertEqual(override.package, asset)\n        self.assertEqual(override.path, 'templates/foo.pt')\n        source = override.source\n        self.assertTrue(isinstance(source, PackageAssetSource))\n        self.assertEqual(source.package, subpackage)\n        self.assertEqual(source.prefix, 'templates/bar.pt')\n    \n        resource_name = ''\n        expected = os.path.join(\n            here, 'pkgs', 'asset', 'subpackage', 'templates', 'bar.pt'\n        )\n>       self.assertEqual(override.source.get_filename(resource_name), expected)\nE       AssertionError: '/hom[90 chars]d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt' != '/hom[90 chars]d114/r2e_tests/test_config/pkgs/asset/subpacka[15 chars]r.pt'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:80: AssertionError\n____ TestAssetsConfiguratorMixin.test_override_asset_package_with_directory ____\n\nself = <r2e_tests.test_config.test_assets.TestAssetsConfiguratorMixin testMethod=test_override_asset_package_with_directory>\n\n    def test_override_asset_package_with_directory(self):\n        from pyramid.config.assets import PackageAssetSource\n    \n        config = self._makeOne(autocommit=True)\n        override = DummyUnderOverride()\n        config.override_asset(\n            'tests.test_config.pkgs.asset',\n            'tests.test_config.pkgs.asset.subpackage:templates/',\n            _override=override,\n        )\n        from tests.test_config.pkgs import asset\n        from tests.test_config.pkgs.asset import subpackage\n    \n        self.assertEqual(override.package, asset)\n        self.assertEqual(override.path, '')\n        source = override.source\n        self.assertTrue(isinstance(source, PackageAssetSource))\n        self.assertEqual(source.package, subpackage)\n        self.assertEqual(source.prefix, 'templates/')\n    \n        resource_name = 'bar.pt'\n        expected = os.path.join(\n            here, 'pkgs', 'asset', 'subpackage', 'templates', 'bar.pt'\n        )\n>       self.assertEqual(override.source.get_filename(resource_name), expected)\nE       AssertionError: '/hom[90 chars]d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt' != '/hom[90 chars]d114/r2e_tests/test_config/pkgs/asset/subpacka[15 chars]r.pt'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:184: AssertionError\n_____ TestAssetsConfiguratorMixin.test_override_asset_package_with_package _____\n\nself = <r2e_tests.test_config.test_assets.TestAssetsConfiguratorMixin testMethod=test_override_asset_package_with_package>\n\n    def test_override_asset_package_with_package(self):\n        from pyramid.config.assets import PackageAssetSource\n    \n        config = self._makeOne(autocommit=True)\n        override = DummyUnderOverride()\n        config.override_asset(\n            'tests.test_config.pkgs.asset',\n            'tests.test_config.pkgs.asset.subpackage',\n            _override=override,\n        )\n        from tests.test_config.pkgs import asset\n        from tests.test_config.pkgs.asset import subpackage\n    \n        self.assertEqual(override.package, asset)\n        self.assertEqual(override.path, '')\n        source = override.source\n        self.assertTrue(isinstance(source, PackageAssetSource))\n        self.assertEqual(source.package, subpackage)\n        self.assertEqual(source.prefix, '')\n    \n        resource_name = 'templates/bar.pt'\n        expected = os.path.join(\n            here, 'pkgs', 'asset', 'subpackage', 'templates', 'bar.pt'\n        )\n>       self.assertEqual(override.source.get_filename(resource_name), expected)\nE       AssertionError: '/hom[90 chars]d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt' != '/hom[90 chars]d114/r2e_tests/test_config/pkgs/asset/subpacka[15 chars]r.pt'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:106: AssertionError\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        resource_name = 'test_assets.py'\n        import tests.test_config\n    \n        provider = self._makeOne(tests.test_config)\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[69 chars]51a07455e958fd0a11926d114/tests/test_config/test_assets.py' != '/hom[69 chars]51a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/test_assets.py\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:360: 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        resource_name = 'test_assets.py'\n        import tests.test_config\n    \n        provider = self._makeOne(tests.test_config)\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[69 chars]51a07455e958fd0a11926d114/tests/test_config/test_assets.py' != '/hom[69 chars]51a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/test_assets.py\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:414: AssertionError\n___________________ TestPackageAssetSource.test_get_filename ___________________\n\nself = <r2e_tests.test_config.test_assets.TestPackageAssetSource testMethod=test_get_filename>\n\n    def test_get_filename(self):\n        source = self._makeOne('')\n>       self.assertEqual(\n            source.get_filename('test_assets.py'),\n            os.path.join(here, 'test_assets.py'),\n        )\nE       AssertionError: '/hom[69 chars]51a07455e958fd0a11926d114/tests/test_config/test_assets.py' != '/hom[69 chars]51a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/test_assets.py\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:830: AssertionError\n_____________ TestPackageAssetSource.test_get_filename_with_prefix _____________\n\nself = <r2e_tests.test_config.test_assets.TestPackageAssetSource testMethod=test_get_filename_with_prefix>\n\n    def test_get_filename_with_prefix(self):\n        source = self._makeOne('test_assets.py')\n>       self.assertEqual(\n            source.get_filename(''), os.path.join(here, 'test_assets.py')\n        )\nE       AssertionError: '/hom[69 chars]51a07455e958fd0a11926d114/tests/test_config/test_assets.py' != '/hom[69 chars]51a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/test_assets.py\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:837: AssertionError\n____________ TestFactoriesMixin.test_set_request_factory_dottedname ____________\n\nself = <r2e_tests.test_config.test_factories.TestFactoriesMixin testMethod=test_set_request_factory_dottedname>\n\n    def test_set_request_factory_dottedname(self):\n        from pyramid.interfaces import IRequestFactory\n    \n        config = self._makeOne(autocommit=True)\n        config.set_request_factory('tests.test_config.dummyfactory')\n>       self.assertEqual(\n            config.registry.getUtility(IRequestFactory), dummyfactory\n        )\nE       AssertionError: <function dummyfactory at 0x782137723670> != <function dummyfactory at 0x782137cf1820>\n\nr2e_tests/test_config/test_factories.py:26: AssertionError\n___________ TestFactoriesMixin.test_set_response_factory_dottedname ____________\n\nself = <r2e_tests.test_config.test_factories.TestFactoriesMixin testMethod=test_set_response_factory_dottedname>\n\n    def test_set_response_factory_dottedname(self):\n        from pyramid.interfaces import IResponseFactory\n    \n        config = self._makeOne(autocommit=True)\n        config.set_response_factory('tests.test_config.dummyfactory')\n>       self.assertEqual(\n            config.registry.getUtility(IResponseFactory), dummyfactory\n        )\nE       AssertionError: <function dummyfactory at 0x782137723670> != <function dummyfactory at 0x782137cf1820>\n\nr2e_tests/test_config/test_factories.py:43: AssertionError\n_____________ TestFactoriesMixin.test_set_root_factory_dottedname ______________\n\nself = <r2e_tests.test_config.test_factories.TestFactoriesMixin testMethod=test_set_root_factory_dottedname>\n\n    def test_set_root_factory_dottedname(self):\n        from pyramid.interfaces import IRootFactory\n    \n        config = self._makeOne()\n        config.set_root_factory('tests.test_config.dummyfactory')\n        self.assertEqual(config.registry.queryUtility(IRootFactory), None)\n        config.commit()\n>       self.assertEqual(\n            config.registry.getUtility(IRootFactory), dummyfactory\n        )\nE       AssertionError: <function dummyfactory at 0x782137723670> != <function dummyfactory at 0x782137cf1820>\n\nr2e_tests/test_config/test_factories.py:77: AssertionError\n____________ TestFactoriesMixin.test_set_session_factory_dottedname ____________\n\nself = <r2e_tests.test_config.test_factories.TestFactoriesMixin testMethod=test_set_session_factory_dottedname>\n\n    def test_set_session_factory_dottedname(self):\n        from pyramid.interfaces import ISessionFactory\n    \n        config = self._makeOne()\n        config.set_session_factory('tests.test_config.dummyfactory')\n        self.assertEqual(config.registry.queryUtility(ISessionFactory), None)\n        config.commit()\n>       self.assertEqual(\n            config.registry.getUtility(ISessionFactory), dummyfactory\n        )\nE       AssertionError: <function dummyfactory at 0x782137723670> != <function dummyfactory at 0x782137cf1820>\n\nr2e_tests/test_config/test_factories.py:99: 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    \n        config = self._makeOne(autocommit=True)\n>       config.add_translation_dirs(locale)\n\nr2e_tests/test_config/test_i18n.py:131: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/actions.py:572: in wrapper\n    result = wrapped(self, *arg, **kw)\nsrc/pyramid/config/i18n.py:125: in add_translation_dirs\n    self.action(None, register, introspectables=introspectables)\nsrc/pyramid/config/actions.py:94: in action\n    callable(*args, **kw)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\n    def register():\n        directories = []\n        resolver = AssetResolver(self.package_name)\n    \n        # defer spec resolution until register to allow for asset\n        # overrides to take place in an earlier config phase\n        for spec in specs:\n            # the trailing slash helps match asset overrides for folders\n            if not spec.endswith('/'):\n                spec += '/'\n            asset = resolver.resolve(spec)\n            directory = asset.abspath()\n            if not asset.isdir():\n>               raise ConfigurationError(\n                    '\"%s\" is not a directory' % directory\n                )\nE               pyramid.exceptions.ConfigurationError: \"/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale\" is not a directory\n\nsrc/pyramid/config/i18n.py:101: 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    \n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs('tests.pkgs.localeapp:locale')\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories), [locale]\n        )\nE       AssertionError: Lists differ: ['/ho[66 chars]898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'] != ['/ho[66 chars]898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale']\nE       \nE       First differing element 0:\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale']\nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale']\nE       ?                                                                                                      ++++\n\nr2e_tests/test_config/test_i18n.py:68: 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    \n        config = self._makeOne(autocommit=True)\n        directories = ['abc']\n        config.registry.registerUtility(directories, ITranslationDirectories)\n        config.add_translation_dirs('tests.pkgs.localeapp:locale')\n        result = config.registry.getUtility(ITranslationDirectories)\n>       self.assertEqual(result, [locale, 'abc'])\nE       AssertionError: Lists differ: ['/ho[73 chars]07455e958fd0a11926d114/tests/pkgs/localeapp/locale', 'abc'] != ['/ho[73 chars]07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale', 'abc']\nE       \nE       First differing element 0:\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale',\nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale',\nE       ?                                                                                                      ++++\nE       \nE          'abc']\n\nr2e_tests/test_config/test_i18n.py:80: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_doesnt_use_override_w_autocommit _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_doesnt_use_override_w_autocommit>\n\n    def test_add_translation_dirs_doesnt_use_override_w_autocommit(self):\n        from pyramid.interfaces import ITranslationDirectories\n    \n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs('tests.pkgs.localeapp:locale')\n        config.override_asset(\n            'tests.pkgs.localeapp:locale/', 'tests.pkgs.localeapp:locale2/'\n        )\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories), [locale]\n        )\nE       AssertionError: Lists differ: ['/ho[66 chars]898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'] != ['/ho[66 chars]898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale']\nE       \nE       First differing element 0:\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale']\nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale']\nE       ?                                                                                                      ++++\n\nr2e_tests/test_config/test_i18n.py:157: 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    \n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs(\n            'tests.pkgs.localeapp:locale', 'tests.pkgs.localeapp:locale2'\n        )\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories),\n            [locale, locale2],\n        )\nE       AssertionError: Lists differ: ['/ho[91 chars]d114/tests/pkgs/localeapp/locale', '/home/gcpu[114 chars]le2'] != ['/ho[91 chars]d114/r2e_tests/pkgs/localeapp/locale', '/home/[122 chars]le2']\nE       \nE       First differing element 0:\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale'\nE       \nE       Diff is 760 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_i18n.py:89: 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    \n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs(\n            'tests.pkgs.localeapp:locale', 'tests.pkgs.localeapp:locale2'\n        )\n        config.add_translation_dirs('tests.pkgs.localeapp:locale3')\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories),\n            [locale3, locale, locale2],\n        )\nE       AssertionError: Lists differ: ['/ho[91 chars]d114/tests/pkgs/localeapp/locale3', '/home/gcp[245 chars]le2'] != ['/ho[91 chars]d114/r2e_tests/pkgs/localeapp/locale3', '/home[257 chars]le2']\nE       \nE       First differing element 0:\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale3'\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale3'\nE       \nE       Diff is 1141 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_i18n.py:102: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_override_multiple_specs_multiple_calls _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_override_multiple_specs_multiple_calls>\n\n    def test_add_translation_dirs_override_multiple_specs_multiple_calls(self):\n        from pyramid.interfaces import ITranslationDirectories\n    \n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs(\n            'tests.pkgs.localeapp:locale', 'tests.pkgs.localeapp:locale2'\n        )\n        config.add_translation_dirs(\n            'tests.pkgs.localeapp:locale3', override=True\n        )\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories),\n            [locale, locale2, locale3],\n        )\nE       AssertionError: Lists differ: ['/ho[91 chars]d114/tests/pkgs/localeapp/locale', '/home/gcpu[245 chars]le3'] != ['/ho[91 chars]d114/r2e_tests/pkgs/localeapp/locale', '/home/[257 chars]le3']\nE       \nE       First differing element 0:\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale'\nE       \nE       Diff is 1141 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_i18n.py:117: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_uses_override_out_of_order _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_uses_override_out_of_order>\n\n    def test_add_translation_dirs_uses_override_out_of_order(self):\n        from pyramid.interfaces import ITranslationDirectories\n    \n        config = self._makeOne()\n        config.add_translation_dirs('tests.pkgs.localeapp:locale')\n        config.override_asset(\n            'tests.pkgs.localeapp:locale/', 'tests.pkgs.localeapp:locale2/'\n        )\n        config.commit()\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories), [locale2]\n        )\nE       AssertionError: Lists differ: ['/ho[67 chars]98251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2'] != ['/ho[67 chars]98251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2']\nE       \nE       First differing element 0:\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2'\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2']\nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2']\nE       ?                                                                                                      ++++\n\nr2e_tests/test_config/test_i18n.py:145: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_uses_override_w_autocommit _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_uses_override_w_autocommit>\n\n    def test_add_translation_dirs_uses_override_w_autocommit(self):\n        from pyramid.interfaces import ITranslationDirectories\n    \n        config = self._makeOne(autocommit=True)\n        config.override_asset(\n            'tests.pkgs.localeapp:locale/', 'tests.pkgs.localeapp:locale2/'\n        )\n        config.add_translation_dirs('tests.pkgs.localeapp:locale')\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories), [locale2]\n        )\nE       AssertionError: Lists differ: ['/ho[67 chars]98251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2'] != ['/ho[67 chars]98251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2']\nE       \nE       First differing element 0:\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2'\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2']\nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2']\nE       ?                                                                                                      ++++\n\nr2e_tests/test_config/test_i18n.py:169: AssertionError\n_______ TestI18NConfiguratorMixin.test_set_locale_negotiator_dottedname ________\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_set_locale_negotiator_dottedname>\n\n    def test_set_locale_negotiator_dottedname(self):\n        from pyramid.interfaces import ILocaleNegotiator\n    \n        config = self._makeOne(autocommit=True)\n        config.set_locale_negotiator('tests.test_config.dummyfactory')\n>       self.assertEqual(\n            config.registry.getUtility(ILocaleNegotiator), dummyfactory\n        )\nE       AssertionError: <function dummyfactory at 0x782137723670> != <function dummyfactory at 0x782137cf1820>\n\nr2e_tests/test_config/test_i18n.py:43: 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    \n        from pyramid.config import Configurator\n        from pyramid.interfaces import IRendererFactory, ISettings\n    \n        config = Configurator()\n        this_pkg = sys.modules['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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:78: 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    \n        config = self._makeOne()\n        logger = config.registry.getUtility(IDebugLogger)\n>       self.assertEqual(logger.name, 'tests.test_config')\nE       AssertionError: 'r2e_tests.test_config' != 'tests.test_config'\nE       - r2e_tests.test_config\nE       ? ----\nE       + tests.test_config\n\nr2e_tests/test_config/test_init.py:204: AssertionError\n_____________ ConfiguratorTests.test_include_constant_root_package _____________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_include_constant_root_package>\n\n    def test_include_constant_root_package(self):\n        import tests\n        from tests import test_config\n    \n        config = self._makeOne(root_package=tests)\n        results = {}\n    \n        def include(config):\n            results['package'] = config.package\n            results['root_package'] = config.root_package\n    \n        config.include(include)\n        self.assertEqual(results['root_package'], tests)\n>       self.assertEqual(results['package'], test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:966: AssertionError\n_____________ ConfiguratorTests.test_include_with_python_callable ______________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_include_with_python_callable>\n\n    def test_include_with_python_callable(self):\n        from tests import test_config\n    \n        config = self._makeOne()\n        config.include(dummy_include)\n        after = config.action_state\n        actions = after.actions\n        self.assertEqual(len(actions), 1)\n        action = actions[0]\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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:878: 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.interfaces import IDebugLogger\n        from pyramid.registry import Registry\n    \n        reg = Registry()\n        config = self._makeOne(reg)\n        config.setup_registry()\n        logger = reg.getUtility(IDebugLogger)\n>       self.assertEqual(logger.name, 'tests.test_config')\nE       AssertionError: 'r2e_tests.test_config' != 'tests.test_config'\nE       - r2e_tests.test_config\nE       ? ----\nE       + tests.test_config\n\nr2e_tests/test_config/test_init.py:594: AssertionError\n_________________ ConfiguratorTests.test_setup_registry_tweens _________________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_setup_registry_tweens>\n\n    def test_setup_registry_tweens(self):\n        from pyramid.interfaces import ITweens\n        from pyramid.registry import Registry\n    \n        reg = Registry()\n        config = self._makeOne(reg)\n        settings = {'pyramid.tweens': 'tests.test_config.dummy_tween_factory'}\n        config.setup_registry(settings=settings)\n        config.commit()\n        tweens = config.registry.getUtility(ITweens)\n>       self.assertEqual(\n            tweens.explicit,\n            [('tests.test_config.dummy_tween_factory', dummy_tween_factory)],\n        )\nE       AssertionError: Lists differ: [('te[25 chars]en_factory', <function dummy_tween_factory at 0x78213780ed30>)] != [('te[25 chars]en_factory', <function dummy_tween_factory at 0x782137cf14c0>)]\nE       \nE       First differing element 0:\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x78213780ed30>)\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x782137cf14c0>)\nE       \nE         [('tests.test_config.dummy_tween_factory',\nE       -   <function dummy_tween_factory at 0x78213780ed30>)]\nE       ?                                            ^^^^^\nE       \nE       +   <function dummy_tween_factory at 0x782137cf14c0>)]\nE       ?                                            ^^^^^\n\nr2e_tests/test_config/test_init.py:815: AssertionError\n__________________ ConfiguratorTests.test_with_package_module __________________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_with_package_module>\n\n    def test_with_package_module(self):\n        from . import test_init\n    \n        config = self._makeOne()\n        newconfig = config.with_package(test_init)\n        import tests.test_config\n    \n>       self.assertEqual(newconfig.package, tests.test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:354: 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 tests import test_config\n    \n        config = self.config\n        config.add_directive(\n            'dummy_callable', 'tests.test_config.dummy_callable'\n        )\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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:1288: 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 tests import test_config\n    \n        config = self.config\n        config.add_directive(\n            'dummy_partial', 'tests.test_config.dummy_partial'\n        )\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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:1273: 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 tests import test_config\n    \n        config = self.config\n        config.add_directive('dummy_extend', '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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:1258: 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 tests import test_config\n    \n        config = self.config\n        config.add_directive('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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:1301: 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(\n            discriminator,\n            callable=None,\n            args=(),\n            kw=None,\n            order=0,\n            introspectables=(),\n            **extra\n        ):\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', 'testing', 'tests.test_config.test_init.DummyPredicate'\n        )\n\nr2e_tests/test_config/test_init.py:1378: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/predicates.py:47: in _add_predicate\n    self.action(\nr2e_tests/test_config/test_init.py:1375: in _fakeAction\n    self.assertEqual(introspectables[0]['factory'], DummyPredicate)\nE   AssertionError: <class 'tests.test_config.test_init.DummyPredicate'> != <class 'r2e_tests.test_config.test_init.DummyPredicate'>\n_____ RoutesConfiguratorMixinTests.test_add_route_with_factory_dottedname ______\n\nself = <r2e_tests.test_config.test_routes.RoutesConfiguratorMixinTests testMethod=test_add_route_with_factory_dottedname>\n\n    def test_add_route_with_factory_dottedname(self):\n        config = self._makeOne(autocommit=True)\n        config.add_route(\n            'name', 'path', factory='tests.test_config.dummyfactory'\n        )\n        route = self._assertRoute(config, 'name', 'path')\n>       self.assertEqual(route.factory, dummyfactory)\nE       AssertionError: <function dummyfactory at 0x782137723670> != <function dummyfactory at 0x782137cf1820>\n\nr2e_tests/test_config/test_routes.py:109: AssertionError\n_____ TestingConfiguratorMixinTests.test_testing_add_subscriber_dottedname _____\n\nself = <r2e_tests.test_config.test_testing.TestingConfiguratorMixinTests testMethod=test_testing_add_subscriber_dottedname>\n\n    def test_testing_add_subscriber_dottedname(self):\n        config = self._makeOne(autocommit=True)\n        L = config.testing_add_subscriber('tests.test_config.IDummy')\n        event = DummyEvent()\n        config.registry.notify(event)\n>       self.assertEqual(len(L), 1)\nE       AssertionError: 0 != 1\n\nr2e_tests/test_config/test_testing.py:108: AssertionError\n____________ TestTweensConfiguratorMixin.test_add_tween_dottedname _____________\n\nself = <r2e_tests.test_config.test_tweens.TestTweensConfiguratorMixin testMethod=test_add_tween_dottedname>\n\n    def test_add_tween_dottedname(self):\n        from pyramid.interfaces import ITweens\n        from pyramid.tweens import excview_tween_factory\n    \n        config = self._makeOne()\n        config.add_tween('tests.test_config.dummy_tween_factory')\n        config.commit()\n        tweens = config.registry.queryUtility(ITweens)\n>       self.assertEqual(\n            tweens.implicit(),\n            [\n                ('tests.test_config.dummy_tween_factory', dummy_tween_factory),\n                (\n                    'pyramid.tweens.excview_tween_factory',\n                    excview_tween_factory,\n                ),\n            ],\n        )\nE       AssertionError: Lists differ: [('te[74 chars]8213780ed30>), ('pyramid.tweens.excview_tween_[57 chars]90>)] != [('te[74 chars]82137cf14c0>), ('pyramid.tweens.excview_tween_[57 chars]90>)]\nE       \nE       First differing element 0:\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x78213780ed30>)\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x782137cf14c0>)\nE       \nE         [('tests.test_config.dummy_tween_factory',\nE       -   <function dummy_tween_factory at 0x78213780ed30>),\nE       ?                                            ^^^^^\nE       \nE       +   <function dummy_tween_factory at 0x782137cf14c0>),\nE       ?                                            ^^^^^\nE       \nE          ('pyramid.tweens.excview_tween_factory',\nE           <function excview_tween_factory at 0x782137c94790>)]\n\nr2e_tests/test_config/test_tweens.py:105: AssertionError\n__________ TestTweensConfiguratorMixin.test_add_tweens_names_distinct __________\n\nself = <r2e_tests.test_config.test_tweens.TestTweensConfiguratorMixin testMethod=test_add_tweens_names_distinct>\n\n    def test_add_tweens_names_distinct(self):\n        from pyramid.interfaces import ITweens\n        from pyramid.tweens import excview_tween_factory\n    \n        def factory1(handler, registry):  # pragma: no cover\n            return handler\n    \n        def factory2(handler, registry):  # pragma: no cover\n            return handler\n    \n        config = self._makeOne()\n        config.add_tween('tests.test_config.dummy_tween_factory')\n        config.add_tween('tests.test_config.dummy_tween_factory2')\n        config.commit()\n        tweens = config.registry.queryUtility(ITweens)\n        implicit = tweens.implicit()\n>       self.assertEqual(\n            implicit,\n            [\n                (\n                    'tests.test_config.dummy_tween_factory2',\n                    dummy_tween_factory2,\n                ),\n                ('tests.test_config.dummy_tween_factory', dummy_tween_factory),\n                (\n                    'pyramid.tweens.excview_tween_factory',\n                    excview_tween_factory,\n                ),\n            ],\n        )\nE       AssertionError: Lists differ: [('te[76 chars]8213780e8b0>), ('tests.test_config.dummy_tween[150 chars]90>)] != [('te[76 chars]82137cf1550>), ('tests.test_config.dummy_tween[150 chars]90>)]\nE       \nE       First differing element 0:\nE       ('tes[25 chars]n_factory2', <function dummy_tween_factory2 at 0x78213780e8b0>)\nE       ('tes[25 chars]n_factory2', <function dummy_tween_factory2 at 0x782137cf1550>)\nE       \nE         [('tests.test_config.dummy_tween_factory2',\nE       -   <function dummy_tween_factory2 at 0x78213780e8b0>),\nE       ?                                             ^^^^^\nE       \nE       +   <function dummy_tween_factory2 at 0x782137cf1550>),\nE       ?                                             ^^^^^\nE       \nE          ('tests.test_config.dummy_tween_factory',\nE       -   <function dummy_tween_factory at 0x78213780ed30>),\nE       ?                                            ^^^^^\nE       \nE       +   <function dummy_tween_factory at 0x782137cf14c0>),\nE       ?                                            ^^^^^\nE       \nE          ('pyramid.tweens.excview_tween_factory',\nE           <function excview_tween_factory at 0x782137c94790>)]\n\nr2e_tests/test_config/test_tweens.py:31: AssertionError\n_______ TestTweensConfiguratorMixin.test_add_tweens_names_with_underover _______\n\nself = <r2e_tests.test_config.test_tweens.TestTweensConfiguratorMixin testMethod=test_add_tweens_names_with_underover>\n\n    def test_add_tweens_names_with_underover(self):\n        from pyramid.interfaces import ITweens\n        from pyramid.tweens import MAIN, excview_tween_factory\n    \n        config = self._makeOne()\n        config.add_tween('tests.test_config.dummy_tween_factory', over=MAIN)\n        config.add_tween(\n            'tests.test_config.dummy_tween_factory2',\n            over=MAIN,\n            under='tests.test_config.dummy_tween_factory',\n        )\n        config.commit()\n        tweens = config.registry.queryUtility(ITweens)\n        implicit = tweens.implicit()\n>       self.assertEqual(\n            implicit,\n            [\n                (\n                    'pyramid.tweens.excview_tween_factory',\n                    excview_tween_factory,\n                ),\n                ('tests.test_config.dummy_tween_factory', dummy_tween_factory),\n                (\n                    'tests.test_config.dummy_tween_factory2',\n                    dummy_tween_factory2,\n                ),\n            ],\n        )\nE       AssertionError: Lists differ: [('py[168 chars]8213780ed30>), ('tests.test_config.dummy_tween[58 chars]b0>)] != [('py[168 chars]82137cf14c0>), ('tests.test_config.dummy_tween[58 chars]50>)]\nE       \nE       First differing element 1:\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x78213780ed30>)\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x782137cf14c0>)\nE       \nE         [('pyramid.tweens.excview_tween_factory',\nE           <function excview_tween_factory at 0x782137c94790>),\nE          ('tests.test_config.dummy_tween_factory',\nE       -   <function dummy_tween_factory at 0x78213780ed30>),\nE       ?                                            ^^^^^\nE       \nE       +   <function dummy_tween_factory at 0x782137cf14c0>),\nE       ?                                            ^^^^^\nE       \nE          ('tests.test_config.dummy_tween_factory2',\nE       -   <function dummy_tween_factory2 at 0x78213780e8b0>)]\nE       ?                                             ^^^^^\nE       \nE       +   <function dummy_tween_factory2 at 0x782137cf1550>)]\nE       ?                                             ^^^^^\n\nr2e_tests/test_config/test_tweens.py:60: AssertionError\n____ TestViewsConfigurationMixin.test_add_exception_view_with_view_defaults ____\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_exception_view_with_view_defaults>\n\n    def test_add_exception_view_with_view_defaults(self):\n        from zope.interface import directlyProvides, implementedBy\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.renderers import null_renderer\n    \n        class view:\n            __view_defaults__ = {'containment': 'tests.test_config.IDummy'}\n    \n            def __init__(self, request):\n                pass\n    \n            def __call__(self):\n                return 'OK'\n    \n        config = self._makeOne(autocommit=True)\n        config.add_exception_view(\n            view=view, context=Exception, renderer=null_renderer\n        )\n        wrapper = self._getViewCallable(\n            config, exc_iface=implementedBy(Exception)\n        )\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n>       self.assertEqual(wrapper(context, request), 'OK')\n\nr2e_tests/test_config/test_views.py:2494: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x7821378d9700>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x7821374dafa0>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view view (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\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 zope.interface import directlyProvides, implementedBy\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n    \n        class view:\n            __view_defaults__ = {'containment': 'tests.test_config.IDummy'}\n    \n            def __init__(self, request):\n                pass\n    \n            def __call__(self):\n                return 'OK'\n    \n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config,\n            exc_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest,\n        )\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n>       self.assertEqual(wrapper(context, request), 'OK')\n\nr2e_tests/test_config/test_views.py:2722: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x7821377ac520>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x782137f6c2e0>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view view (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\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 zope.interface import directlyProvides, implementedBy\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n    \n        class view:\n            __view_defaults__ = {'containment': 'tests.test_config.IDummy'}\n    \n            def __init__(self, request):\n                pass\n    \n            def __call__(self):\n                return 'OK'\n    \n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config,\n            exc_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest,\n        )\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n>       self.assertEqual(wrapper(context, request), 'OK')\n\nr2e_tests/test_config/test_views.py:2890: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x782137a4aa00>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x78213807ef70>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view view (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\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    \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, [(config, 'static', 'tests.test_config:files', {})]\n        )\nE       AssertionError: Lists differ: [(<py[35 chars] 0x782137600580>, 'static', 'r2e_tests.test_config:files', {})] != [(<py[35 chars] 0x782137600580>, 'static', 'tests.test_config:files', {})]\nE       \nE       First differing element 0:\nE       (<pyr[33 chars]t 0x782137600580>, 'static', 'r2e_tests.test_config:files', {})\nE       (<pyr[33 chars]t 0x782137600580>, 'static', 'tests.test_config:files', {})\nE       \nE         [(<pyramid.config.Configurator object at 0x782137600580>,\nE           'static',\nE       -   'r2e_tests.test_config:files',\nE       ?    ----\nE       \nE       +   'tests.test_config:files',\nE           {})]\n\nr2e_tests/test_config/test_views.py:2602: AssertionError\n_______ TestViewsConfigurationMixin.test_add_view_context_as_dottedname ________\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_context_as_dottedname>\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n    \n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            context='tests.test_config.IDummy',\n            view=view,\n            renderer=null_renderer,\n        )\n        wrapper = self._getViewCallable(config, IDummy)\n>       self.assertEqual(wrapper, view)\nE       AssertionError: None != <function TestViewsConfigurationMixin.tes[64 chars]95e0>\n\nr2e_tests/test_config/test_views.py:458: AssertionError\n_________ TestViewsConfigurationMixin.test_add_view_for__as_dottedname _________\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_for__as_dottedname>\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n    \n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            for_='tests.test_config.IDummy', view=view, renderer=null_renderer\n        )\n        wrapper = self._getViewCallable(config, IDummy)\n>       self.assertEqual(wrapper, view)\nE       AssertionError: None != <function TestViewsConfigurationMixin.tes[61 chars]3820>\n\nr2e_tests/test_config/test_views.py:469: AssertionError\n____ TestViewsConfigurationMixin.test_add_view_with_containment_dottedname _____\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_containment_dottedname>\n\n    def test_add_view_with_containment_dottedname(self):\n        from zope.interface import directlyProvides\n    \n        from pyramid.renderers import null_renderer\n    \n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='tests.test_config.IDummy',\n            renderer=null_renderer,\n        )\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n>       self.assertEqual(wrapper(context, None), 'OK')\n\nr2e_tests/test_config/test_views.py:1973: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x78213740ce80>\nrequest = None\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view <lambda> (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\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.interfaces import ISettings\n        from tests import test_config\n    \n        class view:\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n    \n            def __call__(self):\n                return {'a': '1'}\n    \n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = '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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_views.py:1558: 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.interfaces import ISettings\n        from tests import test_config\n    \n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = '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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_views.py:1604: AssertionError\n_________ TestViewsConfigurationMixin.test_add_view_with_view_defaults _________\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_view_defaults>\n\n    def test_add_view_with_view_defaults(self):\n        from zope.interface import directlyProvides\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.renderers import null_renderer\n    \n        class view:\n            __view_defaults__ = {'containment': 'tests.test_config.IDummy'}\n    \n            def __init__(self, request):\n                pass\n    \n            def __call__(self):\n                return 'OK'\n    \n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, 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\nr2e_tests/test_config/test_views.py:2253: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x782137f11610>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x782137f6c7c0>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view view (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\n_ TestViewsConfigurationMixin.test_add_view_with_view_defaults_viewname_is_dottedname_kwarg _\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_view_defaults_viewname_is_dottedname_kwarg>\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from zope.interface import directlyProvides\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.renderers import null_renderer\n    \n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer,\n        )\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\nr2e_tests/test_config/test_views.py:2273: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x782137cd5880>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x782136f01f40>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view DummyViewDefaultsClass (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\n_ TestViewsConfigurationMixin.test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg _\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg>\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from zope.interface import directlyProvides\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.renderers import null_renderer\n    \n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer,\n        )\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\nr2e_tests/test_config/test_views.py:2293: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x782137932f40>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x7821377acf40>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view DummyViewDefaultsClass (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\n_________ TestStaticURLInfo.test_generate_url_cachebust_with_overrides _________\n\nself = <r2e_tests.test_config.test_views.TestStaticURLInfo testMethod=test_generate_url_cachebust_with_overrides>\n\n    def test_generate_url_cachebust_with_overrides(self):\n        config = testing.setUp()\n        try:\n            request = testing.DummyRequest()\n            config.add_static_view('static', 'path')\n            config.override_asset(\n                'tests.test_config:path/', 'tests.test_config:other_path/'\n            )\n    \n            def cb(val):\n                def cb_(request, subpath, kw):\n                    kw['_query'] = {'x': val}\n                    return subpath, kw\n    \n                return cb_\n    \n            config.add_cache_buster('path', cb('foo'))\n            result = request.static_url('path/foo.png')\n            self.assertEqual(result, 'http://example.com/static/foo.png?x=foo')\n            config.add_cache_buster('other_path', cb('bar'), explicit=True)\n            result = request.static_url('path/foo.png')\n>           self.assertEqual(result, 'http://example.com/static/foo.png?x=bar')\nE           AssertionError: 'http://example.com/static/foo.png?x=foo' != 'http://example.com/static/foo.png?x=bar'\nE           - http://example.com/static/foo.png?x=foo\nE           ?                                     ^^^\nE           + http://example.com/static/foo.png?x=bar\nE           ?                                     ^^^\n\nr2e_tests/test_config/test_views.py:4085: 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():  # pragma: no cover\n            pass\n    \n        result = self._callFUT(view)\n>       self.assertEqual(result, 'function tests.test_config.test_views.view')\nE       AssertionError: 'function r2e_tests.test_config.test_views.view' != 'function tests.test_config.test_views.view'\nE       - function r2e_tests.test_config.test_views.view\nE       ?          ----\nE       + function tests.test_config.test_views.view\n\nr2e_tests/test_config/test_views.py:4289: AssertionError\n______________________ TestPRoutesCommand.test_class_view ______________________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_class_view>\n\n    def test_class_view(self):\n        from pyramid.renderers import null_renderer as nr\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(\n            route_name='foo',\n            view=dummy.DummyView,\n            attr='view',\n            renderer=nr,\n            request_method='POST',\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.dummy.DummyView.view',\n            'POST',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.dummy.DummyView.view', 'POST'] != ['foo', '/a/b', 'tests.test_scripts.dummy.DummyView.view', 'POST']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.dummy.DummyView.view'\nE       'tests.test_scripts.dummy.DummyView.view'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.dummy.DummyView.view', 'POST']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.dummy.DummyView.view', 'POST']\n\nr2e_tests/test_scripts/test_proutes.py:247: AssertionError\n_________ TestPRoutesCommand.test_one_route_all_methods_view_only_post _________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_one_route_all_methods_view_only_post>\n\n    def test_one_route_all_methods_view_only_post(self):\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(\n            route_name='foo', view=view1, renderer=nr, request_method='POST'\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            'POST',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\n\nr2e_tests/test_scripts/test_proutes.py:362: AssertionError\n_________ TestPRoutesCommand.test_one_route_only_post_view_all_methods _________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_one_route_only_post_view_all_methods>\n\n    def test_one_route_only_post_view_all_methods(self):\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b', request_method='POST')\n        config.add_view(route_name='foo', view=view1, renderer=nr)\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            'POST',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\n\nr2e_tests/test_scripts/test_proutes.py:388: AssertionError\n________ TestPRoutesCommand.test_one_route_only_post_view_post_and_get _________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_one_route_only_post_view_post_and_get>\n\n    def test_one_route_only_post_view_post_and_get(self):\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b', request_method='POST')\n        config.add_view(\n            route_name='foo',\n            view=view1,\n            renderer=nr,\n            request_method=('POST', 'GET'),\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            'POST',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\n\nr2e_tests/test_scripts/test_proutes.py:419: AssertionError\n_____ TestPRoutesCommand.test_one_route_with_long_name_one_view_registered _____\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_one_route_with_long_name_one_view_registered>\n\n    def test_one_route_with_long_name_one_view_registered(self):\n        from zope.interface import Interface\n    \n        from pyramid.interfaces import IRouteRequest, IView, IViewClassifier\n    \n        registry = self._makeRegistry()\n    \n        def view():  # pragma: no cover\n            pass\n    \n        class IMyRoute(Interface):\n            pass\n    \n        registry.registerAdapter(\n            view, (IViewClassifier, IMyRoute, Interface), IView, ''\n        )\n    \n        registry.registerUtility(\n            IMyRoute, IRouteRequest, name='very_long_name_123'\n        )\n    \n        command = self._makeOne()\n        route = dummy.DummyRoute(\n            'very_long_name_123', '/and_very_long_pattern_as_well'\n        )\n        mapper = dummy.DummyMapper(route)\n        command._get_mapper = lambda *arg: mapper\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()[:3]\n>       self.assertEqual(\n            compare_to,\n            [\n                'very_long_name_123',\n                '/and_very_long_pattern_as_well',\n                'tests.test_scripts.test_proutes.view',\n            ],\n        )\nE       AssertionError: Lists differ: ['ver[32 chars]g_pattern_as_well', 'r2e_tests.test_scripts.test_proutes.view'] != ['ver[32 chars]g_pattern_as_well', 'tests.test_scripts.test_proutes.view']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view'\nE       'tests.test_scripts.test_proutes.view'\nE       \nE         ['very_long_name_123',\nE          '/and_very_long_pattern_as_well',\nE       -  'r2e_tests.test_scripts.test_proutes.view']\nE       ?   ----\nE       \nE       +  'tests.test_scripts.test_proutes.view']\n\nr2e_tests/test_scripts/test_proutes.py:211: AssertionError\n______ TestPRoutesCommand.test_route_is_get_view_request_method_not_post _______\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_route_is_get_view_request_method_not_post>\n\n    def test_route_is_get_view_request_method_not_post(self):\n        from pyramid.config import not_\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b', request_method='GET')\n        config.add_view(\n            route_name='foo',\n            view=view1,\n            renderer=nr,\n            request_method=not_('POST'),\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            'GET',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'GET'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'GET']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'GET']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'GET']\n\nr2e_tests/test_scripts/test_proutes.py:559: AssertionError\n____________ TestPRoutesCommand.test_route_request_method_mismatch _____________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_route_request_method_mismatch>\n\n    def test_route_request_method_mismatch(self):\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b', request_method='POST')\n        config.add_view(\n            route_name='foo', view=view1, renderer=nr, request_method='GET'\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            '<route',\n            'mismatch>',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1[20 chars]ch>'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '[16 chars]ch>']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '<route', 'mismatch>']\nE       - ['foo',\nE       -  '/a/b',\nE       -  'r2e_tests.test_scripts.test_proutes.view1',\nE       -  '<route',\nE       -  'mismatch>']\n\nr2e_tests/test_scripts/test_proutes.py:448: AssertionError\n__________________ TestPRoutesCommand.test_route_static_views __________________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_route_static_views>\n\n    def test_route_static_views(self):\n        config = self._makeConfig(autocommit=True)\n        config.add_static_view('static', 'static', cache_max_age=3600)\n        path2 = os.path.normpath('/var/www/static')\n        config.add_static_view(name='static2', path=path2)\n        config.add_static_view(\n            name='pyramid_scaffold',\n            path='pyramid:scaffolds/starter/+package+/static',\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 5)\n    \n        expected = [\n            [\n                '__static/',\n                '/static/*subpath',\n                'tests.test_scripts:static/',\n                '*',\n            ],\n            ['__static2/', '/static2/*subpath', path2 + os.sep, '*'],\n            [\n                '__pyramid_scaffold/',\n                '/pyramid_scaffold/*subpath',\n                'pyramid:scaffolds/starter/+package+/static/',\n                '*',\n            ],\n        ]\n    \n        for index, line in enumerate(L[2:]):\n            data = line.split()\n>           self.assertEqual(data, expected[index])\nE           AssertionError: Lists differ: ['__static/', '/static/*subpath', 'r2e_tests.test_scripts:static/', '*'] != ['__static/', '/static/*subpath', 'tests.test_scripts:static/', '*']\nE           \nE           First differing element 2:\nE           'r2e_tests.test_scripts:static/'\nE           'tests.test_scripts:static/'\nE           \nE           - ['__static/', '/static/*subpath', 'r2e_tests.test_scripts:static/', '*']\nE           ?                                    ----\nE           \nE           + ['__static/', '/static/*subpath', 'tests.test_scripts:static/', '*']\n\nr2e_tests/test_scripts/test_proutes.py:486: AssertionError\n__________ TestPRoutesCommand.test_single_route_multiview_registered ___________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_single_route_multiview_registered>\n\n    def test_single_route_multiview_registered(self):\n        from zope.interface import Interface\n    \n        from pyramid.interfaces import (\n            IMultiView,\n            IRouteRequest,\n            IViewClassifier,\n        )\n    \n        registry = self._makeRegistry()\n    \n        def view():  # pragma: no cover\n            pass\n    \n        class IMyRoute(Interface):\n            pass\n    \n        multiview1 = dummy.DummyMultiView(\n            view, context='context', view_name='a1'\n        )\n    \n        registry.registerAdapter(\n            multiview1, (IViewClassifier, IMyRoute, Interface), IMultiView, ''\n        )\n        registry.registerUtility(IMyRoute, IRouteRequest, name='a')\n        command = self._makeOne()\n        route = dummy.DummyRoute('a', '/a')\n        mapper = dummy.DummyMapper(route)\n        command._get_mapper = lambda *arg: mapper\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()[:3]\n        view_module = 'tests.test_scripts.dummy'\n        view_str = '<tests.test_scripts.dummy.DummyMultiView'\n        final = '%s.%s' % (view_module, view_str)\n    \n>       self.assertEqual(compare_to, ['a', '/a', final])\nE       AssertionError: Lists differ: ['a', '/a', 'r2e_tests.test_scripts.dummy.<r2e_tests.t[29 chars]iew'] != ['a', '/a', 'tests.test_scripts.dummy.<tests.test_scri[21 chars]iew']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.dummy.<r2e_tests.test_scripts.dummy.DummyMultiView'\nE       'tests.test_scripts.dummy.<tests.test_scripts.dummy.DummyMultiView'\nE       \nE       - ['a',\nE       -  '/a',\nE       -  'r2e_tests.test_scripts.dummy.<r2e_tests.test_scripts.dummy.DummyMultiView']\nE       ? ^ ^^^^                          ----\nE       \nE       + ['a', '/a', 'tests.test_scripts.dummy.<tests.test_scripts.dummy.DummyMultiView']\nE       ? ^ ^^^^^^^^^^^\n\nr2e_tests/test_scripts/test_proutes.py:325: AssertionError\n___________ TestPRoutesCommand.test_single_route_one_view_registered ___________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_single_route_one_view_registered>\n\n    def test_single_route_one_view_registered(self):\n        from zope.interface import Interface\n    \n        from pyramid.interfaces import IRouteRequest, IView, IViewClassifier\n    \n        registry = self._makeRegistry()\n    \n        def view():  # pragma: no cover\n            pass\n    \n        class IMyRoute(Interface):\n            pass\n    \n        registry.registerAdapter(\n            view, (IViewClassifier, IMyRoute, Interface), IView, ''\n        )\n        registry.registerUtility(IMyRoute, IRouteRequest, name='a')\n        command = self._makeOne()\n        route = dummy.DummyRoute('a', '/a')\n        mapper = dummy.DummyMapper(route)\n        command._get_mapper = lambda *arg: mapper\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()[:3]\n>       self.assertEqual(\n            compare_to, ['a', '/a', 'tests.test_scripts.test_proutes.view']\n        )\nE       AssertionError: Lists differ: ['a', '/a', 'r2e_tests.test_scripts.test_proutes.view'] != ['a', '/a', 'tests.test_scripts.test_proutes.view']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view'\nE       'tests.test_scripts.test_proutes.view'\nE       \nE       - ['a', '/a', 'r2e_tests.test_scripts.test_proutes.view']\nE       ?              ----\nE       \nE       + ['a', '/a', 'tests.test_scripts.test_proutes.view']\n\nr2e_tests/test_scripts/test_proutes.py:173: AssertionError\n______________________ TestPRoutesCommand.test_view_glob _______________________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_view_glob>\n\n    def test_view_glob(self):\n        from pyramid.config import not_\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        def view2(context, request):  # pragma: no cover\n            return 'view2'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(\n            route_name='foo',\n            view=view1,\n            renderer=nr,\n            request_method=not_('POST'),\n        )\n    \n        config.add_route('bar', '/b/a')\n        config.add_view(\n            route_name='bar',\n            view=view2,\n            renderer=nr,\n            request_method=not_('POST'),\n        )\n    \n        command = self._makeOne()\n        command.args.glob = '*foo*'\n    \n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            '!POST,*',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', '!POST,*'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '!POST,*']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', '!POST,*']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '!POST,*']\n\nr2e_tests/test_scripts/test_proutes.py:636: AssertionError\n_____________ TestPRoutesCommand.test_view_request_method_not_post _____________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_view_request_method_not_post>\n\n    def test_view_request_method_not_post(self):\n        from pyramid.config import not_\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(\n            route_name='foo',\n            view=view1,\n            renderer=nr,\n            request_method=not_('POST'),\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            '!POST,*',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', '!POST,*'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '!POST,*']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', '!POST,*']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '!POST,*']\n\nr2e_tests/test_scripts/test_proutes.py:591: AssertionError\n_____________ TestPServeCommand.test_config_file_finds_watch_files _____________\n\nself = <r2e_tests.test_scripts.test_pserve.TestPServeCommand testMethod=test_config_file_finds_watch_files>\n\n    def test_config_file_finds_watch_files(self):\n        inst = self._makeOne('development.ini')\n        loader = self.loader('/base/path.ini')\n        loader.settings = {\n            'pserve': {'watch_files': 'foo\\n/baz\\ntests.test_scripts:*.py'}\n        }\n        inst.pserve_file_config(loader, global_conf={'a': '1'})\n        self.assertEqual(loader.calls[0]['defaults'], {'a': '1'})\n>       self.assertEqual(\n            inst.watch_files,\n            {\n                os.path.abspath('/base/foo'),\n                os.path.abspath('/baz'),\n                os.path.abspath(os.path.join(here, '*.py')),\n            },\n        )\nE       AssertionError: Items in the first set but not the second:\nE       '/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_scripts/*.py'\nE       Items in the second set but not the first:\nE       '/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_scripts/*.py'\n\nr2e_tests/test_scripts/test_pserve.py:90: AssertionError\n____________ TestPViewsCommand.test_views_command_multi_view_nested ____________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_multi_view_nested>\n\n    def test_views_command_multi_view_nested(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        view1 = dummy.DummyView(context='context', view_name='a1')\n        view1.__name__ = 'view1'\n        view1.__view_attr__ = 'call'\n        multiview1 = dummy.DummyMultiView(\n            view1, context='context', view_name='a1'\n        )\n        multiview2 = dummy.DummyMultiView(\n            multiview1, context='context', view_name='a'\n        )\n        command._find_view = lambda arg1: multiview2\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.DummyMultiView')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.DummyMultiView' != '    tests.test_scripts.dummy.DummyMultiView'\nE       -     r2e_tests.test_scripts.dummy.DummyMultiView\nE       ?     ----\nE       +     tests.test_scripts.dummy.DummyMultiView\n\nr2e_tests/test_scripts/test_pviews.py:475: AssertionError\n________________ TestPViewsCommand.test_views_command_multiview ________________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_multiview>\n\n    def test_views_command_multiview(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        view = dummy.DummyView(context='context')\n        view.__name__ = 'view'\n        view.__view_attr__ = 'call'\n        multiview = dummy.DummyMultiView(\n            view, context='context', view_name='a'\n        )\n        command._find_view = lambda arg1: multiview\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.view.call')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.view.call' != '    tests.test_scripts.dummy.view.call'\nE       -     r2e_tests.test_scripts.dummy.view.call\nE       ?     ----\nE       +     tests.test_scripts.dummy.view.call\n\nr2e_tests/test_scripts/test_pviews.py:531: AssertionError\n________ TestPViewsCommand.test_views_command_multiview_with_permission ________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_multiview_with_permission>\n\n    def test_views_command_multiview_with_permission(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        view = dummy.DummyView(context='context')\n        view.__name__ = 'view'\n        view.__view_attr__ = 'call'\n        view.__permission__ = 'test'\n        multiview = dummy.DummyMultiView(\n            view, context='context', view_name='a'\n        )\n        command._find_view = lambda arg1: multiview\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.view.call')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.view.call' != '    tests.test_scripts.dummy.view.call'\nE       -     r2e_tests.test_scripts.dummy.view.call\nE       ?     ----\nE       +     tests.test_scripts.dummy.view.call\n\nr2e_tests/test_scripts/test_pviews.py:555: AssertionError\n________ TestPViewsCommand.test_views_command_multiview_with_predicates ________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_multiview_with_predicates>\n\n    def test_views_command_multiview_with_predicates(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n    \n        def predicate():  # pragma: no cover\n            pass\n    \n        predicate.text = lambda *arg: \"predicate = x\"\n        view = dummy.DummyView(context='context')\n        view.__name__ = 'view'\n        view.__view_attr__ = 'call'\n        view.__predicates__ = [predicate]\n        multiview = dummy.DummyMultiView(\n            view, context='context', view_name='a'\n        )\n        command._find_view = lambda arg1: multiview\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.view.call')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.view.call' != '    tests.test_scripts.dummy.view.call'\nE       -     r2e_tests.test_scripts.dummy.view.call\nE       ?     ----\nE       +     tests.test_scripts.dummy.view.call\n\nr2e_tests/test_scripts/test_pviews.py:585: 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    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n    \n        def view():  # pragma: no cover\n            pass\n    \n        view.__request_attrs__ = {'context': 'context', 'view_name': 'a'}\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.test_pviews.view')\nE       AssertionError: '    r2e_tests.test_scripts.test_pviews.view' != '    tests.test_scripts.test_pviews.view'\nE       -     r2e_tests.test_scripts.test_pviews.view\nE       ?     ----\nE       +     tests.test_scripts.test_pviews.view\n\nr2e_tests/test_scripts/test_pviews.py:378: AssertionError\n____________ TestPViewsCommand.test_views_command_single_view_route ____________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_route>\n\n    def test_views_command_single_view_route(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        route = dummy.DummyRoute('a', '/a', matchdict={})\n        view = dummy.DummyView(\n            context='context', view_name='a', matched_route=route, subpath=''\n        )\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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[6], '    Route:')\n        self.assertEqual(L[8], '    route name: a')\n        self.assertEqual(L[9], '    route pattern: /a')\n        self.assertEqual(L[10], '    route path: /a')\n        self.assertEqual(L[11], '    subpath: ')\n>       self.assertEqual(L[15], '        tests.test_scripts.dummy.DummyView')\nE       AssertionError: '        r2e_tests.test_scripts.dummy.DummyView' != '        tests.test_scripts.dummy.DummyView'\nE       -         r2e_tests.test_scripts.dummy.DummyView\nE       ?         ----\nE       +         tests.test_scripts.dummy.DummyView\n\nr2e_tests/test_scripts/test_pviews.py:449: AssertionError\n_ TestPViewsCommand.test_views_command_single_view_route_with_route_predicates _\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_route_with_route_predicates>\n\n    def test_views_command_single_view_route_with_route_predicates(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n    \n        def predicate():  # pragma: no cover\n            pass\n    \n        predicate.text = lambda *arg: \"predicate = x\"\n        route = dummy.DummyRoute('a', '/a', matchdict={}, predicate=predicate)\n        view = dummy.DummyView(\n            context='context', view_name='a', matched_route=route, subpath=''\n        )\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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[6], '    Route:')\n        self.assertEqual(L[8], '    route name: a')\n        self.assertEqual(L[9], '    route pattern: /a')\n        self.assertEqual(L[10], '    route path: /a')\n        self.assertEqual(L[11], '    subpath: ')\n        self.assertEqual(L[12], '    route predicates (predicate = x)')\n>       self.assertEqual(L[16], '        tests.test_scripts.dummy.DummyView')\nE       AssertionError: '        r2e_tests.test_scripts.dummy.DummyView' != '        tests.test_scripts.dummy.DummyView'\nE       -         r2e_tests.test_scripts.dummy.DummyView\nE       ?         ----\nE       +         tests.test_scripts.dummy.DummyView\n\nr2e_tests/test_scripts/test_pviews.py:508: AssertionError\n__________ TestPViewsCommand.test_views_command_single_view_traversal __________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_traversal>\n\n    def test_views_command_single_view_traversal(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        view = dummy.DummyView(context='context', view_name='a')\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.DummyView')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.DummyView' != '    tests.test_scripts.dummy.DummyView'\nE       -     r2e_tests.test_scripts.dummy.DummyView\nE       ?     ----\nE       +     tests.test_scripts.dummy.DummyView\n\nr2e_tests/test_scripts/test_pviews.py:356: AssertionError\n__ TestPViewsCommand.test_views_command_single_view_traversal_with_permission __\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_traversal_with_permission>\n\n    def test_views_command_single_view_traversal_with_permission(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        view = dummy.DummyView(context='context', view_name='a')\n        view.__permission__ = 'test'\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.DummyView')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.DummyView' != '    tests.test_scripts.dummy.DummyView'\nE       -     r2e_tests.test_scripts.dummy.DummyView\nE       ?     ----\nE       +     tests.test_scripts.dummy.DummyView\n\nr2e_tests/test_scripts/test_pviews.py:397: AssertionError\n__ TestPViewsCommand.test_views_command_single_view_traversal_with_predicates __\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_traversal_with_predicates>\n\n    def test_views_command_single_view_traversal_with_predicates(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n    \n        def predicate():  # pragma: no cover\n            pass\n    \n        predicate.text = lambda *arg: \"predicate = x\"\n        view = dummy.DummyView(context='context', view_name='a')\n        view.__predicates__ = [predicate]\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.DummyView')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.DummyView' != '    tests.test_scripts.dummy.DummyView'\nE       -     r2e_tests.test_scripts.dummy.DummyView\nE       ?     ----\nE       +     tests.test_scripts.dummy.DummyView\n\nr2e_tests/test_scripts/test_pviews.py:422: AssertionError\n=============================== warnings summary ===============================\nsrc/pyramid/asset.py:2\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/src/pyramid/asset.py:2: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html\n    import pkg_resources\n\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('paste')`.\n  Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages\n    declare_namespace(pkg)\n\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('zope')`.\n  Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages\n    declare_namespace(pkg)\n\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_authentication_policy\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_authorization_policy_only\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy_dottedname\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authorization_policy_dottedname\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authorization_policy_only\nr2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_no_default_permission_no_explicit_permission\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/src/pyramid/config/__init__.py:405: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    self.set_authorization_policy(authorization_policy)\n\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_authentication_policy\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy_dottedname\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authorization_policy_dottedname\nr2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_no_default_permission_no_explicit_permission\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/src/pyramid/config/__init__.py:408: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    self.set_authentication_policy(authentication_policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_no_authz_policy\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:37: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authentication_policy(policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_no_authz_policy_autocommit\n  /home/gcpuser/.local/share/uv/python/cpython-3.8.20-linux-x86_64-gnu/lib/python3.8/unittest/case.py:202: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    callable_obj(*args, **kwargs)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_with_authz_policy\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:59: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authentication_policy(authn_policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_with_authz_policy_autocommit\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:80: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authentication_policy(authn_policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_with_security_policy\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:31: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authentication_policy(authn_policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_no_authn_policy\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:92: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authorization_policy(policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_no_authn_policy_autocommit\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:100: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authorization_policy(policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_with_authn_policy\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:115: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authorization_policy(authz_policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_with_authn_policy_autocommit\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:131: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authorization_policy(authz_policy)\n\n-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n==================================== PASSES ====================================\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::TestRouter::test_call_eventsends\nPASSED r2e_tests/test_1.py::TestRouter::test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview\nPASSED r2e_tests/test_1.py::TestRouter::test_call_no_view_registered_debug_notfound_false\nPASSED r2e_tests/test_1.py::TestRouter::test_call_no_view_registered_debug_notfound_true\nPASSED r2e_tests/test_1.py::TestRouter::test_call_no_view_registered_no_isettings\nPASSED r2e_tests/test_1.py::TestRouter::test_call_request_factory_raises\nPASSED r2e_tests/test_1.py::TestRouter::test_call_request_has_response_callbacks\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_match_miss_debug_routematch\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_matches_and_has_factory\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_matches_doesnt_overwrite_subscriber_iface\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_exception_another_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_exception_view_another_route\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_exception_view_specializing\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_route_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_sub_exception_super_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_super_exception_sub_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_traverser_default\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_exception_propagating\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_multiple_predicate_mismatches_dont_hide_views\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_predicate_mismatch_doesnt_find_unrelated_views\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_predicate_mismatch_doesnt_hide_views\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_exception_another_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_exception_route_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_exception_view_route\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_forbidden\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_notfound\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_predicate_mismatch\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_response_cleared\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_sub_exception_super_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_super_exception_sub_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_registered_nonspecific_default_path\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_registered_nonspecific_nondefault_path_and_subpath\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_registered_specific_fail\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_registered_specific_success\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_returns_adapted_response\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_returns_non_iresponse\nPASSED r2e_tests/test_1.py::TestRouter::test_call_with_request_extensions\nPASSED r2e_tests/test_1.py::TestRouter::test_ctor_registry_has_no_settings\nPASSED r2e_tests/test_1.py::TestRouter::test_custom_execution_policy\nPASSED r2e_tests/test_1.py::TestRouter::test_exception_view_returns_non_iresponse\nPASSED r2e_tests/test_1.py::TestRouter::test_execution_policy_bubbles_exception\nPASSED r2e_tests/test_1.py::TestRouter::test_finish_request_when_view_raises\nPASSED r2e_tests/test_1.py::TestRouter::test_finish_request_when_view_succeeds\nPASSED r2e_tests/test_1.py::TestRouter::test_request_context_manually\nPASSED r2e_tests/test_1.py::TestRouter::test_request_context_with_statement\nPASSED r2e_tests/test_1.py::TestRouter::test_request_factory\nPASSED r2e_tests/test_1.py::TestRouter::test_root_factory_exception_propagating\nPASSED r2e_tests/test_1.py::TestRouter::test_root_factory_raises_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_root_factory_raises_forbidden\nPASSED r2e_tests/test_1.py::TestRouter::test_root_factory_raises_notfound\nPASSED r2e_tests/test_1.py::TestRouter::test_root_policy\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_exception_propagating\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_raises_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_raises_forbidden_class\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_raises_forbidden_instance\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_raises_notfound_class\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_raises_notfound_instance\nPASSED r2e_tests/test_1.py::TestRouter::test_tween_factories\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_autocommit_with_introspectables\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_autocommit_with_introspectables_introspection_off\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_branching_kw_is_None\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_branching_kw_is_not_None\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_branching_nonautocommit_with_config_info\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_branching_nonautocommit_with_introspectables\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_branching_nonautocommit_without_config_info\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_nonautocommit_with_introspectables_introspection_off\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_autocommit_no_conflicts\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_commit_conflict_resolved_with_include\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_commit_conflict_resolved_with_two_includes_and_local\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_commit_conflict_simple\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_commit_conflict_with_two_includes\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_conflict_set_forbidden_view\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_conflict_set_notfound_view\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_simple\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_with_includepath\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_with_includepath_and_info\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_with_info\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_with_introspectables\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_with_order\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_execute_actions_dicts\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_execute_actions_error\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_execute_actions_tuples\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_execute_actions_with_introspectable_no_callable\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_execute_actions_with_introspectables\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_executing_conflicting_action_across_orders\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_executing_conflicting_action_across_reentrant_orders\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_it\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_processSpec\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_reentrant_action\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_reentrant_action_error\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_reentrant_action_with_deferred_discriminator\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_reentrant_action_without_clear\nPASSED r2e_tests/test_config/test_actions.py::Test_reentrant_action_functional::test_deferred_discriminator\nPASSED r2e_tests/test_config/test_actions.py::Test_reentrant_action_functional::test_functional\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_conflicts_across_orders\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_it_conflict\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_it_success_dicts\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_it_success_tuples\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_it_with_actions_grouped_by_order\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_override_success_across_orders\nPASSED r2e_tests/test_config/test_actions.py::TestActionInfo::test___str__\nPASSED r2e_tests/test_config/test_actions.py::TestActionInfo::test_class_conforms\nPASSED r2e_tests/test_config/test_actions.py::TestActionInfo::test_ctor\nPASSED r2e_tests/test_config/test_actions.py::TestActionInfo::test_instance_conforms\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_absdirectory\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_directory_with_absfile\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_file_with_absdirectory\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_file_with_absfile\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_missing_abspath\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_absdirectory\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_filtered_sources\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\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::TestPackageAssetSource::test_exists\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_exists_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_exists_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_filename_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_stream\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_stream_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_stream_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_string\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_string_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_string_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_isdir_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_isdir_false\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_isdir_true\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_listdir\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_listdir_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_exists\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_exists_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_exists_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_filename\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_filename_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_filename_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_stream\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_stream_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_stream_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_string\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_string_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_string_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_isdir_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_isdir_false\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_isdir_true\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_listdir\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_listdir_doesnt_exist\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_text_name\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_execution_policy\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_execution_policy_to_None\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_response_factory\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_session_factory\nPASSED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_invalid_kwargs\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_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_adds__lock\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test__fix_registry_adds_clear_view_lookup_cache\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_begin\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin_does_not_propagate_request_for_diff_registry\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin_overrides_request\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin_propagates_request_for_same_registry\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin_with_request\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_context_manager\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_security_policy\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_threadlocals_active\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_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_conflict\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_response_factory\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_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::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::TestPredicateList::test_custom_predicates_can_affect_traversal\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_different_custom_predicates_with_same_hash\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple_mixed\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple_mixed_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple_with_values\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple_with_values_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_simple\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_simple_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_with_value\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_with_value_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_with_value_fails_case\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_is_authenticated_false_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_is_authenticated_false_matches\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_is_authenticated_true_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_is_authenticated_true_matches\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_match_param_from_dict\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_match_param_from_dict_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_match_param_from_string\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_match_param_from_string_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_notted\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_ordering_importance_and_number\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_ordering_importance_of_predicates\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_ordering_number_of_predicates\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_ordering_xhr_and_request_method_trump_only_containment\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_predicate_close_matches\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_predicate_text_is_correct\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_predicate_text_is_correct_when_multiple\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_request_method_ordering_hashes_same\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_request_method_sequence\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_traverse_has_remainder_already\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_traverse_matches\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_traverse_matches_with_highorder_chars\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_unknown_predicate\nPASSED r2e_tests/test_config/test_predicates.py::Test_sort_accept_offers::test_default_specificities\nPASSED r2e_tests/test_config/test_predicates.py::Test_sort_accept_offers::test_params_inherit_type_prefs\nPASSED r2e_tests/test_config/test_predicates.py::Test_sort_accept_offers::test_params_order\nPASSED r2e_tests/test_config/test_predicates.py::Test_sort_accept_offers::test_specific_type_order\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_effective_principals_deprecated\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_accept_list\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_header\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_inherit_errors\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_is_authenticated\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_root_slash_with_route_prefix\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_route_prefix_with_inherit_slash\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_wildcard_accept_raises\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_changing_set_default_csrf_options\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_authentication_policy_with_security_policy\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_csrf_options\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_default_permission\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_security_policy\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__set_settings_does_not_uses_original_dict\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::TestSettingsConfiguratorMixin::test_settings_parameter_dict_is_never_updated\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_csrf_trusted_origins\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_noargs\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_originals_kept\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_prevent_cachebust\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_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_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_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::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_views.py::TestViewsConfigurationMixin::test_add_accept_view_order_override\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_accept_view_order_throws_on_type_mismatch\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_accept_view_order_throws_on_wildcard\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_disallows_exception_only\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_disallows_for_\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_disallows_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_disallows_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_disallows_require_csrf\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_with_subclass\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_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_disallows_require_csrf\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_no_view_argument\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_normal_and_exception_view_intr_derived_callable\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_append_slash_custom_response\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_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_disallows_require_csrf\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_no_view_argument\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_class_method_no_attr\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_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_custom_predicate_bests_standard_predicate\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_does_not_accept_iterable_accept\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_multiviews\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_only_exc_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_only\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exception_only_misconfiguration\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exception_only_no_regular_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_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_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_csrf_header\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_csrf_param\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_nomatch\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_is_authenticated_false_matches\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_is_authenticated_false_no_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_is_authenticated_true_matches\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_is_authenticated_true_no_match\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_missing_csrf_header\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_wildcard_accept_raises\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_default_accept_view_order\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_effective_principals_deprecated\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::TestViewsConfigurationMixin::test_view_with_most_specific_predicate\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_view_with_most_specific_predicate_with_mismatch\nPASSED r2e_tests/test_config/test_views.py::Test_runtime_exc_view::test_call\nPASSED r2e_tests/test_config/test_views.py::Test_runtime_exc_view::test_call_dispatches_on_exception\nPASSED r2e_tests/test_config/test_views.py::Test_runtime_exc_view::test_permitted\nPASSED r2e_tests/test_config/test_views.py::Test_runtime_exc_view::test_permitted_dispatches_on_exception\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::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_cachebust_prevented\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_cachebuster\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_cachebuster_abspath\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_cachebuster_for_more_specific_path\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_cachebuster_overwrite\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_cachebuster_overwrite_explicit\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_package_root\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_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_cachebust\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_cachebust_abspath\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_cachebust_nomatch\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_generate_url_with_custom_anchor\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_with_custom_query\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_config/test_views.py::Test_viewdefaults::test_dunder_attrs_copied\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_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_display_headers\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_has_content_type_header_var\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_good_header_var\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_multiple_header_vars\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_configures_logging\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_get\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_options\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_patch\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_post\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_propfind\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_put\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_path_doesnt_start_with_slash\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_response_has_no_charset\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_two_args\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_w_basic_auth\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_with_query_string\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_bad_format\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_config_format_ini_commas\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_config_format_ini_newlines\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_config_format_ini_spaces\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_good_args\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_good_format\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_as_wsgiapp\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_route_no_view\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_with_factory\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_static_routes_included_in_list\nPASSED r2e_tests/test_scripts/test_proutes.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_config_file_finds_open_url\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_guess_server_url\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_original_ignore_files\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_reload_call_hupper_with_correct_args\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_run_no_args\nPASSED r2e_tests/test_scripts/test_pserve.py::Test_main::test_it\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_default_shell_option\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_errors_with_unknown_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_ipython\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_pythonstartup\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_command_setup_generator\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_list_shells\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_shell_entry_points\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_shell_ordering\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_shell_override\nPASSED r2e_tests/test_scripts/test_pshell.py::Test_python_shell_runner::test_it\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_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::Test_main::test_it\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::TestAssetsConfiguratorMixin::test_override_asset_directory_with_directory\nFAILED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_directory_with_package\nFAILED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_file_with_file\nFAILED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_package_with_directory\nFAILED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_package_with_package\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::TestPackageAssetSource::test_get_filename\nFAILED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_filename_with_prefix\nFAILED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_request_factory_dottedname\nFAILED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_response_factory_dottedname\nFAILED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_root_factory_dottedname\nFAILED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_session_factory_dottedname\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_doesnt_use_override_w_autocommit\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_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_override_multiple_specs_multiple_calls\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_uses_override_out_of_order\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_uses_override_w_autocommit\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_set_locale_negotiator_dottedname\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_include_constant_root_package\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_python_callable\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_debug_logger_None_default\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_tweens\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_with_package_module\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_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_factory_dottedname\nFAILED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_subscriber_dottedname\nFAILED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_dottedname\nFAILED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_distinct\nFAILED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_with_underover\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_with_view_defaults\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_context_as_dottedname\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_for__as_dottedname\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_containment_dottedname\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::TestViewsConfigurationMixin::test_add_view_with_view_defaults\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_kwarg\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg\nFAILED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_cachebust_with_overrides\nFAILED r2e_tests/test_config/test_views.py::Test_view_description::test_without_text\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_class_view\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_one_route_all_methods_view_only_post\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_one_route_only_post_view_all_methods\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_one_route_only_post_view_post_and_get\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_one_route_with_long_name_one_view_registered\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_route_is_get_view_request_method_not_post\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_route_request_method_mismatch\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_route_static_views\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_multiview_registered\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_one_view_registered\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_view_glob\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_view_request_method_not_post\nFAILED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_config_file_finds_watch_files\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multi_view_nested\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview_with_permission\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview_with_predicates\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_function_traversal\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_route\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_route_with_route_predicates\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal_with_permission\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal_with_predicates\n================= 80 failed, 805 passed, 28 warnings in 6.55s ==================\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_68c84ae5aa2898251a07455e958fd0a11926d114\nconfigfile: setup.cfg\nplugins: cov-5.0.0\ncollected 885 items\n\nr2e_tests/test_1.py ...........................................FF....... [  5%]\n........                                                                 [  6%]\nr2e_tests/test_config/test_actions.py .................................. [ 10%]\n............                                                             [ 11%]\nr2e_tests/test_config/test_adapters.py .FF..............F...             [ 14%]\nr2e_tests/test_config/test_assets.py ....F.F...F...FF.FF................ [ 18%]\n.....................................F.F................................ [ 26%]\n                                                                         [ 26%]\nr2e_tests/test_config/test_factories.py ..........F.F..F.F               [ 28%]\nr2e_tests/test_config/test_i18n.py FFFF..FF.FFF.F                        [ 30%]\nr2e_tests/test_config/test_init.py .............................F..F.... [ 34%]\n....F......F...................F................F..F.FF...FFF...         [ 41%]\nr2e_tests/test_config/test_predicates.py ............................... [ 44%]\n........                                                                 [ 45%]\nr2e_tests/test_config/test_rendering.py ...                              [ 46%]\nr2e_tests/test_config/test_routes.py .............F.................     [ 49%]\nr2e_tests/test_config/test_security.py ..............                    [ 51%]\nr2e_tests/test_config/test_settings.py ........................          [ 54%]\nr2e_tests/test_config/test_testing.py ....F.......                       [ 55%]\nr2e_tests/test_config/test_tweens.py F.........F..F...................   [ 59%]\nr2e_tests/test_config/test_views.py ..........F.........F............F.. [ 63%]\nF.........F....................F....................F................... [ 71%]\n..............................FF.....FFF................................ [ 79%]\n.................................................................F...... [ 87%]\n.F.                                                                      [ 87%]\nr2e_tests/test_scripts/test_common.py ..                                 [ 88%]\nr2e_tests/test_scripts/test_pdistreport.py ..                            [ 88%]\nr2e_tests/test_scripts/test_prequest.py ...................              [ 90%]\nr2e_tests/test_scripts/test_proutes.py ...F.......FFFF.F.FF.F..F..FF.    [ 93%]\nr2e_tests/test_scripts/test_pserve.py .F.......                          [ 94%]\nr2e_tests/test_scripts/test_pshell.py .................                  [ 96%]\nr2e_tests/test_scripts/test_ptweens.py .....                             [ 97%]\nr2e_tests/test_scripts/test_pviews.py ..........FFFF..FFFFFF.            [100%]\n\n=================================== FAILURES ===================================\n_______________ TestRouter.test_finish_request_when_view_raises ________________\n\nself = <r2e_tests.test_1.TestRouter testMethod=test_finish_request_when_view_raises>\n\n    def test_finish_request_when_view_raises(self):\n        from zope.interface import Interface, directlyProvides\n    \n        class IContext(Interface):\n            pass\n    \n        from pyramid.interfaces import IRequest, IViewClassifier\n    \n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n    \n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n    \n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            raise NotImplementedError\n    \n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        exc_raised(NotImplementedError, router, environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n>       self.assertFalse(hasattr(environ['request'], 'context'))\nE       AssertionError: True is not false\n\nr2e_tests/test_1.py:692: AssertionError\n______________ TestRouter.test_finish_request_when_view_succeeds _______________\n\nself = <r2e_tests.test_1.TestRouter testMethod=test_finish_request_when_view_succeeds>\n\n    def test_finish_request_when_view_succeeds(self):\n        from zope.interface import Interface, directlyProvides\n    \n        class IContext(Interface):\n            pass\n    \n        from pyramid.interfaces import IRequest, IViewClassifier\n    \n        context = DummyContext()\n        directlyProvides(context, IContext)\n        self._registerTraverserFactory(context, subpath=[''])\n        response = DummyResponse('200 OK')\n    \n        def view(context, request):\n            def callback(request):\n                request.environ['called_back'] = True\n    \n            request.add_finished_callback(callback)\n            request.environ['request'] = request\n            return response\n    \n        environ = self._makeEnviron()\n        self._registerView(view, '', IViewClassifier, IRequest, IContext)\n        router = self._makeOne()\n        start_response = DummyStartResponse()\n        router(environ, start_response)\n        self.assertEqual(environ['called_back'], True)\n>       self.assertFalse(hasattr(environ['request'], 'context'))\nE       AssertionError: True is not false\n\nr2e_tests/test_1.py:664: 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    \n        config = self._makeOne(autocommit=True)\n        config.add_resource_url_adapter(\n            'tests.test_config.test_adapters.DummyResourceURL',\n            'tests.test_config.test_adapters.DummyIface',\n        )\n        iface = DummyIface()\n>       adapter = config.registry.getMultiAdapter((iface, iface), IResourceURL)\n\nr2e_tests/test_config/test_adapters.py:325: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <Registry r2e_tests.test_config>\nobjects = (<r2e_tests.test_config.test_adapters.DummyIface object at 0x7ec39f24e7f0>, <r2e_tests.test_config.test_adapters.DummyIface object at 0x7ec39f24e7f0>)\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 0x7ec39f24e7f0>, <r2e_tests.test_config.test_adapters.DummyIface object at 0x7ec39f24e7f0>), <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(\n            intr.discriminator, ('resource url adapter', DummyIface)\n        )\n        self.assertEqual(intr.category_name, 'resource url adapters')\n>       self.assertEqual(\n            intr.title,\n            \"resource url adapter for resource iface \"\n            \"<class 'tests.test_config.test_adapters.DummyIface'>\",\n        )\nE       AssertionError: \"reso[30 chars]iface <class 'r2e_tests.test_config.test_adapters.DummyIface'>\" != \"reso[30 chars]iface <class '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 'tests.test_config.test_adapters.DummyIface'>\n\nr2e_tests/test_config/test_adapters.py:371: 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    \n        config = self._makeOne(autocommit=True)\n        config.add_traverser(\n            'tests.test_config.test_adapters.DummyTraverser',\n            'tests.test_config.test_adapters.DummyIface',\n        )\n        iface = DummyIface()\n>       traverser = config.registry.getAdapter(iface, ITraverser)\n\nr2e_tests/test_config/test_adapters.py:279: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\nself = <Registry r2e_tests.test_config>\nobject = <r2e_tests.test_config.test_adapters.DummyIface object at 0x7ec39f258040>\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 0x7ec39f258040>, <InterfaceClass pyramid.interfaces.ITraverser>, '')\n\n.venv/lib/python3.8/site-packages/zope/interface/registry.py:368: ComponentLookupError\n___ TestAssetsConfiguratorMixin.test_override_asset_directory_with_directory ___\n\nself = <r2e_tests.test_config.test_assets.TestAssetsConfiguratorMixin testMethod=test_override_asset_directory_with_directory>\n\n    def test_override_asset_directory_with_directory(self):\n        from pyramid.config.assets import PackageAssetSource\n    \n        config = self._makeOne(autocommit=True)\n        override = DummyUnderOverride()\n        config.override_asset(\n            'tests.test_config.pkgs.asset:templates/',\n            'tests.test_config.pkgs.asset.subpackage:templates/',\n            _override=override,\n        )\n        from tests.test_config.pkgs import asset\n        from tests.test_config.pkgs.asset import subpackage\n    \n        self.assertEqual(override.package, asset)\n        self.assertEqual(override.path, 'templates/')\n        source = override.source\n        self.assertTrue(isinstance(source, PackageAssetSource))\n        self.assertEqual(source.package, subpackage)\n        self.assertEqual(source.prefix, 'templates/')\n    \n        resource_name = 'bar.pt'\n        expected = os.path.join(\n            here, 'pkgs', 'asset', 'subpackage', 'templates', 'bar.pt'\n        )\n>       self.assertEqual(override.source.get_filename(resource_name), expected)\nE       AssertionError: '/hom[90 chars]d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt' != '/hom[90 chars]d114/r2e_tests/test_config/pkgs/asset/subpacka[15 chars]r.pt'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:132: AssertionError\n____ TestAssetsConfiguratorMixin.test_override_asset_directory_with_package ____\n\nself = <r2e_tests.test_config.test_assets.TestAssetsConfiguratorMixin testMethod=test_override_asset_directory_with_package>\n\n    def test_override_asset_directory_with_package(self):\n        from pyramid.config.assets import PackageAssetSource\n    \n        config = self._makeOne(autocommit=True)\n        override = DummyUnderOverride()\n        config.override_asset(\n            'tests.test_config.pkgs.asset:templates/',\n            'tests.test_config.pkgs.asset.subpackage',\n            _override=override,\n        )\n        from tests.test_config.pkgs import asset\n        from tests.test_config.pkgs.asset import subpackage\n    \n        self.assertEqual(override.package, asset)\n        self.assertEqual(override.path, 'templates/')\n        source = override.source\n        self.assertTrue(isinstance(source, PackageAssetSource))\n        self.assertEqual(source.package, subpackage)\n        self.assertEqual(source.prefix, '')\n    \n        resource_name = 'templates/bar.pt'\n        expected = os.path.join(\n            here, 'pkgs', 'asset', 'subpackage', 'templates', 'bar.pt'\n        )\n>       self.assertEqual(override.source.get_filename(resource_name), expected)\nE       AssertionError: '/hom[90 chars]d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt' != '/hom[90 chars]d114/r2e_tests/test_config/pkgs/asset/subpacka[15 chars]r.pt'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:158: AssertionError\n________ TestAssetsConfiguratorMixin.test_override_asset_file_with_file ________\n\nself = <r2e_tests.test_config.test_assets.TestAssetsConfiguratorMixin testMethod=test_override_asset_file_with_file>\n\n    def test_override_asset_file_with_file(self):\n        from pyramid.config.assets import PackageAssetSource\n    \n        config = self._makeOne(autocommit=True)\n        override = DummyUnderOverride()\n        config.override_asset(\n            'tests.test_config.pkgs.asset:templates/foo.pt',\n            'tests.test_config.pkgs.asset.subpackage:templates/bar.pt',\n            _override=override,\n        )\n        from tests.test_config.pkgs import asset\n        from tests.test_config.pkgs.asset import subpackage\n    \n        self.assertEqual(override.package, asset)\n        self.assertEqual(override.path, 'templates/foo.pt')\n        source = override.source\n        self.assertTrue(isinstance(source, PackageAssetSource))\n        self.assertEqual(source.package, subpackage)\n        self.assertEqual(source.prefix, 'templates/bar.pt')\n    \n        resource_name = ''\n        expected = os.path.join(\n            here, 'pkgs', 'asset', 'subpackage', 'templates', 'bar.pt'\n        )\n>       self.assertEqual(override.source.get_filename(resource_name), expected)\nE       AssertionError: '/hom[90 chars]d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt' != '/hom[90 chars]d114/r2e_tests/test_config/pkgs/asset/subpacka[15 chars]r.pt'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:80: AssertionError\n____ TestAssetsConfiguratorMixin.test_override_asset_package_with_directory ____\n\nself = <r2e_tests.test_config.test_assets.TestAssetsConfiguratorMixin testMethod=test_override_asset_package_with_directory>\n\n    def test_override_asset_package_with_directory(self):\n        from pyramid.config.assets import PackageAssetSource\n    \n        config = self._makeOne(autocommit=True)\n        override = DummyUnderOverride()\n        config.override_asset(\n            'tests.test_config.pkgs.asset',\n            'tests.test_config.pkgs.asset.subpackage:templates/',\n            _override=override,\n        )\n        from tests.test_config.pkgs import asset\n        from tests.test_config.pkgs.asset import subpackage\n    \n        self.assertEqual(override.package, asset)\n        self.assertEqual(override.path, '')\n        source = override.source\n        self.assertTrue(isinstance(source, PackageAssetSource))\n        self.assertEqual(source.package, subpackage)\n        self.assertEqual(source.prefix, 'templates/')\n    \n        resource_name = 'bar.pt'\n        expected = os.path.join(\n            here, 'pkgs', 'asset', 'subpackage', 'templates', 'bar.pt'\n        )\n>       self.assertEqual(override.source.get_filename(resource_name), expected)\nE       AssertionError: '/hom[90 chars]d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt' != '/hom[90 chars]d114/r2e_tests/test_config/pkgs/asset/subpacka[15 chars]r.pt'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:184: AssertionError\n_____ TestAssetsConfiguratorMixin.test_override_asset_package_with_package _____\n\nself = <r2e_tests.test_config.test_assets.TestAssetsConfiguratorMixin testMethod=test_override_asset_package_with_package>\n\n    def test_override_asset_package_with_package(self):\n        from pyramid.config.assets import PackageAssetSource\n    \n        config = self._makeOne(autocommit=True)\n        override = DummyUnderOverride()\n        config.override_asset(\n            'tests.test_config.pkgs.asset',\n            'tests.test_config.pkgs.asset.subpackage',\n            _override=override,\n        )\n        from tests.test_config.pkgs import asset\n        from tests.test_config.pkgs.asset import subpackage\n    \n        self.assertEqual(override.package, asset)\n        self.assertEqual(override.path, '')\n        source = override.source\n        self.assertTrue(isinstance(source, PackageAssetSource))\n        self.assertEqual(source.package, subpackage)\n        self.assertEqual(source.prefix, '')\n    \n        resource_name = 'templates/bar.pt'\n        expected = os.path.join(\n            here, 'pkgs', 'asset', 'subpackage', 'templates', 'bar.pt'\n        )\n>       self.assertEqual(override.source.get_filename(resource_name), expected)\nE       AssertionError: '/hom[90 chars]d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt' != '/hom[90 chars]d114/r2e_tests/test_config/pkgs/asset/subpacka[15 chars]r.pt'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/pkgs/asset/subpackage/templates/bar.pt\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:106: AssertionError\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        resource_name = 'test_assets.py'\n        import tests.test_config\n    \n        provider = self._makeOne(tests.test_config)\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[69 chars]51a07455e958fd0a11926d114/tests/test_config/test_assets.py' != '/hom[69 chars]51a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/test_assets.py\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:360: 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        resource_name = 'test_assets.py'\n        import tests.test_config\n    \n        provider = self._makeOne(tests.test_config)\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[69 chars]51a07455e958fd0a11926d114/tests/test_config/test_assets.py' != '/hom[69 chars]51a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/test_assets.py\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:414: AssertionError\n___________________ TestPackageAssetSource.test_get_filename ___________________\n\nself = <r2e_tests.test_config.test_assets.TestPackageAssetSource testMethod=test_get_filename>\n\n    def test_get_filename(self):\n        source = self._makeOne('')\n>       self.assertEqual(\n            source.get_filename('test_assets.py'),\n            os.path.join(here, 'test_assets.py'),\n        )\nE       AssertionError: '/hom[69 chars]51a07455e958fd0a11926d114/tests/test_config/test_assets.py' != '/hom[69 chars]51a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/test_assets.py\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:830: AssertionError\n_____________ TestPackageAssetSource.test_get_filename_with_prefix _____________\n\nself = <r2e_tests.test_config.test_assets.TestPackageAssetSource testMethod=test_get_filename_with_prefix>\n\n    def test_get_filename_with_prefix(self):\n        source = self._makeOne('test_assets.py')\n>       self.assertEqual(\n            source.get_filename(''), os.path.join(here, 'test_assets.py')\n        )\nE       AssertionError: '/hom[69 chars]51a07455e958fd0a11926d114/tests/test_config/test_assets.py' != '/hom[69 chars]51a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py'\nE       - /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_config/test_assets.py\nE       + /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_assets.py\nE       ?                                                                                                    ++++\n\nr2e_tests/test_config/test_assets.py:837: AssertionError\n____________ TestFactoriesMixin.test_set_request_factory_dottedname ____________\n\nself = <r2e_tests.test_config.test_factories.TestFactoriesMixin testMethod=test_set_request_factory_dottedname>\n\n    def test_set_request_factory_dottedname(self):\n        from pyramid.interfaces import IRequestFactory\n    \n        config = self._makeOne(autocommit=True)\n        config.set_request_factory('tests.test_config.dummyfactory')\n>       self.assertEqual(\n            config.registry.getUtility(IRequestFactory), dummyfactory\n        )\nE       AssertionError: <function dummyfactory at 0x7ec39f28e8b0> != <function dummyfactory at 0x7ec39f8193a0>\n\nr2e_tests/test_config/test_factories.py:26: AssertionError\n___________ TestFactoriesMixin.test_set_response_factory_dottedname ____________\n\nself = <r2e_tests.test_config.test_factories.TestFactoriesMixin testMethod=test_set_response_factory_dottedname>\n\n    def test_set_response_factory_dottedname(self):\n        from pyramid.interfaces import IResponseFactory\n    \n        config = self._makeOne(autocommit=True)\n        config.set_response_factory('tests.test_config.dummyfactory')\n>       self.assertEqual(\n            config.registry.getUtility(IResponseFactory), dummyfactory\n        )\nE       AssertionError: <function dummyfactory at 0x7ec39f28e8b0> != <function dummyfactory at 0x7ec39f8193a0>\n\nr2e_tests/test_config/test_factories.py:43: AssertionError\n_____________ TestFactoriesMixin.test_set_root_factory_dottedname ______________\n\nself = <r2e_tests.test_config.test_factories.TestFactoriesMixin testMethod=test_set_root_factory_dottedname>\n\n    def test_set_root_factory_dottedname(self):\n        from pyramid.interfaces import IRootFactory\n    \n        config = self._makeOne()\n        config.set_root_factory('tests.test_config.dummyfactory')\n        self.assertEqual(config.registry.queryUtility(IRootFactory), None)\n        config.commit()\n>       self.assertEqual(\n            config.registry.getUtility(IRootFactory), dummyfactory\n        )\nE       AssertionError: <function dummyfactory at 0x7ec39f28e8b0> != <function dummyfactory at 0x7ec39f8193a0>\n\nr2e_tests/test_config/test_factories.py:77: AssertionError\n____________ TestFactoriesMixin.test_set_session_factory_dottedname ____________\n\nself = <r2e_tests.test_config.test_factories.TestFactoriesMixin testMethod=test_set_session_factory_dottedname>\n\n    def test_set_session_factory_dottedname(self):\n        from pyramid.interfaces import ISessionFactory\n    \n        config = self._makeOne()\n        config.set_session_factory('tests.test_config.dummyfactory')\n        self.assertEqual(config.registry.queryUtility(ISessionFactory), None)\n        config.commit()\n>       self.assertEqual(\n            config.registry.getUtility(ISessionFactory), dummyfactory\n        )\nE       AssertionError: <function dummyfactory at 0x7ec39f28e8b0> != <function dummyfactory at 0x7ec39f8193a0>\n\nr2e_tests/test_config/test_factories.py:99: 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    \n        config = self._makeOne(autocommit=True)\n>       config.add_translation_dirs(locale)\n\nr2e_tests/test_config/test_i18n.py:131: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/actions.py:572: in wrapper\n    result = wrapped(self, *arg, **kw)\nsrc/pyramid/config/i18n.py:125: in add_translation_dirs\n    self.action(None, register, introspectables=introspectables)\nsrc/pyramid/config/actions.py:94: in action\n    callable(*args, **kw)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\n    def register():\n        directories = []\n        resolver = AssetResolver(self.package_name)\n    \n        # defer spec resolution until register to allow for asset\n        # overrides to take place in an earlier config phase\n        for spec in specs:\n            # the trailing slash helps match asset overrides for folders\n            if not spec.endswith('/'):\n                spec += '/'\n            asset = resolver.resolve(spec)\n            directory = asset.abspath()\n            if not asset.isdir():\n>               raise ConfigurationError(\n                    '\"%s\" is not a directory' % directory\n                )\nE               pyramid.exceptions.ConfigurationError: \"/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale\" is not a directory\n\nsrc/pyramid/config/i18n.py:101: 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    \n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs('tests.pkgs.localeapp:locale')\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories), [locale]\n        )\nE       AssertionError: Lists differ: ['/ho[66 chars]898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'] != ['/ho[66 chars]898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale']\nE       \nE       First differing element 0:\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale']\nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale']\nE       ?                                                                                                      ++++\n\nr2e_tests/test_config/test_i18n.py:68: 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    \n        config = self._makeOne(autocommit=True)\n        directories = ['abc']\n        config.registry.registerUtility(directories, ITranslationDirectories)\n        config.add_translation_dirs('tests.pkgs.localeapp:locale')\n        result = config.registry.getUtility(ITranslationDirectories)\n>       self.assertEqual(result, [locale, 'abc'])\nE       AssertionError: Lists differ: ['/ho[73 chars]07455e958fd0a11926d114/tests/pkgs/localeapp/locale', 'abc'] != ['/ho[73 chars]07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale', 'abc']\nE       \nE       First differing element 0:\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale',\nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale',\nE       ?                                                                                                      ++++\nE       \nE          'abc']\n\nr2e_tests/test_config/test_i18n.py:80: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_doesnt_use_override_w_autocommit _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_doesnt_use_override_w_autocommit>\n\n    def test_add_translation_dirs_doesnt_use_override_w_autocommit(self):\n        from pyramid.interfaces import ITranslationDirectories\n    \n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs('tests.pkgs.localeapp:locale')\n        config.override_asset(\n            'tests.pkgs.localeapp:locale/', 'tests.pkgs.localeapp:locale2/'\n        )\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories), [locale]\n        )\nE       AssertionError: Lists differ: ['/ho[66 chars]898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'] != ['/ho[66 chars]898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale']\nE       \nE       First differing element 0:\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale']\nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale']\nE       ?                                                                                                      ++++\n\nr2e_tests/test_config/test_i18n.py:157: 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    \n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs(\n            'tests.pkgs.localeapp:locale', 'tests.pkgs.localeapp:locale2'\n        )\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories),\n            [locale, locale2],\n        )\nE       AssertionError: Lists differ: ['/ho[91 chars]d114/tests/pkgs/localeapp/locale', '/home/gcpu[114 chars]le2'] != ['/ho[91 chars]d114/r2e_tests/pkgs/localeapp/locale', '/home/[122 chars]le2']\nE       \nE       First differing element 0:\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale'\nE       \nE       Diff is 760 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_i18n.py:89: 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    \n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs(\n            'tests.pkgs.localeapp:locale', 'tests.pkgs.localeapp:locale2'\n        )\n        config.add_translation_dirs('tests.pkgs.localeapp:locale3')\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories),\n            [locale3, locale, locale2],\n        )\nE       AssertionError: Lists differ: ['/ho[91 chars]d114/tests/pkgs/localeapp/locale3', '/home/gcp[245 chars]le2'] != ['/ho[91 chars]d114/r2e_tests/pkgs/localeapp/locale3', '/home[257 chars]le2']\nE       \nE       First differing element 0:\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale3'\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale3'\nE       \nE       Diff is 1141 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_i18n.py:102: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_override_multiple_specs_multiple_calls _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_override_multiple_specs_multiple_calls>\n\n    def test_add_translation_dirs_override_multiple_specs_multiple_calls(self):\n        from pyramid.interfaces import ITranslationDirectories\n    \n        config = self._makeOne(autocommit=True)\n        config.add_translation_dirs(\n            'tests.pkgs.localeapp:locale', 'tests.pkgs.localeapp:locale2'\n        )\n        config.add_translation_dirs(\n            'tests.pkgs.localeapp:locale3', override=True\n        )\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories),\n            [locale, locale2, locale3],\n        )\nE       AssertionError: Lists differ: ['/ho[91 chars]d114/tests/pkgs/localeapp/locale', '/home/gcpu[245 chars]le3'] != ['/ho[91 chars]d114/r2e_tests/pkgs/localeapp/locale', '/home/[257 chars]le3']\nE       \nE       First differing element 0:\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale'\nE       '/hom[64 chars]2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale'\nE       \nE       Diff is 1141 characters long. Set self.maxDiff to None to see it.\n\nr2e_tests/test_config/test_i18n.py:117: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_uses_override_out_of_order _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_uses_override_out_of_order>\n\n    def test_add_translation_dirs_uses_override_out_of_order(self):\n        from pyramid.interfaces import ITranslationDirectories\n    \n        config = self._makeOne()\n        config.add_translation_dirs('tests.pkgs.localeapp:locale')\n        config.override_asset(\n            'tests.pkgs.localeapp:locale/', 'tests.pkgs.localeapp:locale2/'\n        )\n        config.commit()\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories), [locale2]\n        )\nE       AssertionError: Lists differ: ['/ho[67 chars]98251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2'] != ['/ho[67 chars]98251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2']\nE       \nE       First differing element 0:\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2'\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2']\nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2']\nE       ?                                                                                                      ++++\n\nr2e_tests/test_config/test_i18n.py:145: AssertionError\n_ TestI18NConfiguratorMixin.test_add_translation_dirs_uses_override_w_autocommit _\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_add_translation_dirs_uses_override_w_autocommit>\n\n    def test_add_translation_dirs_uses_override_w_autocommit(self):\n        from pyramid.interfaces import ITranslationDirectories\n    \n        config = self._makeOne(autocommit=True)\n        config.override_asset(\n            'tests.pkgs.localeapp:locale/', 'tests.pkgs.localeapp:locale2/'\n        )\n        config.add_translation_dirs('tests.pkgs.localeapp:locale')\n>       self.assertEqual(\n            config.registry.getUtility(ITranslationDirectories), [locale2]\n        )\nE       AssertionError: Lists differ: ['/ho[67 chars]98251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2'] != ['/ho[67 chars]98251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2']\nE       \nE       First differing element 0:\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2'\nE       '/hom[65 chars]898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2'\nE       \nE       - ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/pkgs/localeapp/locale2']\nE       + ['/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/pkgs/localeapp/locale2']\nE       ?                                                                                                      ++++\n\nr2e_tests/test_config/test_i18n.py:169: AssertionError\n_______ TestI18NConfiguratorMixin.test_set_locale_negotiator_dottedname ________\n\nself = <r2e_tests.test_config.test_i18n.TestI18NConfiguratorMixin testMethod=test_set_locale_negotiator_dottedname>\n\n    def test_set_locale_negotiator_dottedname(self):\n        from pyramid.interfaces import ILocaleNegotiator\n    \n        config = self._makeOne(autocommit=True)\n        config.set_locale_negotiator('tests.test_config.dummyfactory')\n>       self.assertEqual(\n            config.registry.getUtility(ILocaleNegotiator), dummyfactory\n        )\nE       AssertionError: <function dummyfactory at 0x7ec39f28e8b0> != <function dummyfactory at 0x7ec39f8193a0>\n\nr2e_tests/test_config/test_i18n.py:43: 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    \n        from pyramid.config import Configurator\n        from pyramid.interfaces import IRendererFactory, ISettings\n    \n        config = Configurator()\n        this_pkg = sys.modules['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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:78: 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    \n        config = self._makeOne()\n        logger = config.registry.getUtility(IDebugLogger)\n>       self.assertEqual(logger.name, 'tests.test_config')\nE       AssertionError: 'r2e_tests.test_config' != 'tests.test_config'\nE       - r2e_tests.test_config\nE       ? ----\nE       + tests.test_config\n\nr2e_tests/test_config/test_init.py:204: AssertionError\n_____________ ConfiguratorTests.test_include_constant_root_package _____________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_include_constant_root_package>\n\n    def test_include_constant_root_package(self):\n        import tests\n        from tests import test_config\n    \n        config = self._makeOne(root_package=tests)\n        results = {}\n    \n        def include(config):\n            results['package'] = config.package\n            results['root_package'] = config.root_package\n    \n        config.include(include)\n        self.assertEqual(results['root_package'], tests)\n>       self.assertEqual(results['package'], test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:966: AssertionError\n_____________ ConfiguratorTests.test_include_with_python_callable ______________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_include_with_python_callable>\n\n    def test_include_with_python_callable(self):\n        from tests import test_config\n    \n        config = self._makeOne()\n        config.include(dummy_include)\n        after = config.action_state\n        actions = after.actions\n        self.assertEqual(len(actions), 1)\n        action = actions[0]\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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:878: 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.interfaces import IDebugLogger\n        from pyramid.registry import Registry\n    \n        reg = Registry()\n        config = self._makeOne(reg)\n        config.setup_registry()\n        logger = reg.getUtility(IDebugLogger)\n>       self.assertEqual(logger.name, 'tests.test_config')\nE       AssertionError: 'r2e_tests.test_config' != 'tests.test_config'\nE       - r2e_tests.test_config\nE       ? ----\nE       + tests.test_config\n\nr2e_tests/test_config/test_init.py:594: AssertionError\n_________________ ConfiguratorTests.test_setup_registry_tweens _________________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_setup_registry_tweens>\n\n    def test_setup_registry_tweens(self):\n        from pyramid.interfaces import ITweens\n        from pyramid.registry import Registry\n    \n        reg = Registry()\n        config = self._makeOne(reg)\n        settings = {'pyramid.tweens': 'tests.test_config.dummy_tween_factory'}\n        config.setup_registry(settings=settings)\n        config.commit()\n        tweens = config.registry.getUtility(ITweens)\n>       self.assertEqual(\n            tweens.explicit,\n            [('tests.test_config.dummy_tween_factory', dummy_tween_factory)],\n        )\nE       AssertionError: Lists differ: [('te[25 chars]en_factory', <function dummy_tween_factory at 0x7ec39f260670>)] != [('te[25 chars]en_factory', <function dummy_tween_factory at 0x7ec39f819040>)]\nE       \nE       First differing element 0:\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x7ec39f260670>)\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x7ec39f819040>)\nE       \nE         [('tests.test_config.dummy_tween_factory',\nE       -   <function dummy_tween_factory at 0x7ec39f260670>)]\nE       ?                                            ^^ ^^\nE       \nE       +   <function dummy_tween_factory at 0x7ec39f819040>)]\nE       ?                                            ^^^ ^\n\nr2e_tests/test_config/test_init.py:815: AssertionError\n__________________ ConfiguratorTests.test_with_package_module __________________\n\nself = <r2e_tests.test_config.test_init.ConfiguratorTests testMethod=test_with_package_module>\n\n    def test_with_package_module(self):\n        from . import test_init\n    \n        config = self._makeOne()\n        newconfig = config.with_package(test_init)\n        import tests.test_config\n    \n>       self.assertEqual(newconfig.package, tests.test_config)\nE       AssertionError: <module 'r2e_tests.test_config' from '/home/gcpuse[117 chars].py'> != <module 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:354: 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 tests import test_config\n    \n        config = self.config\n        config.add_directive(\n            'dummy_callable', 'tests.test_config.dummy_callable'\n        )\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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:1288: 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 tests import test_config\n    \n        config = self.config\n        config.add_directive(\n            'dummy_partial', 'tests.test_config.dummy_partial'\n        )\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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:1273: 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 tests import test_config\n    \n        config = self.config\n        config.add_directive('dummy_extend', '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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:1258: 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 tests import test_config\n    \n        config = self.config\n        config.add_directive('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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_init.py:1301: 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(\n            discriminator,\n            callable=None,\n            args=(),\n            kw=None,\n            order=0,\n            introspectables=(),\n            **extra\n        ):\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', 'testing', 'tests.test_config.test_init.DummyPredicate'\n        )\n\nr2e_tests/test_config/test_init.py:1378: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/predicates.py:47: in _add_predicate\n    self.action(\nr2e_tests/test_config/test_init.py:1375: in _fakeAction\n    self.assertEqual(introspectables[0]['factory'], DummyPredicate)\nE   AssertionError: <class 'tests.test_config.test_init.DummyPredicate'> != <class 'r2e_tests.test_config.test_init.DummyPredicate'>\n_____ RoutesConfiguratorMixinTests.test_add_route_with_factory_dottedname ______\n\nself = <r2e_tests.test_config.test_routes.RoutesConfiguratorMixinTests testMethod=test_add_route_with_factory_dottedname>\n\n    def test_add_route_with_factory_dottedname(self):\n        config = self._makeOne(autocommit=True)\n        config.add_route(\n            'name', 'path', factory='tests.test_config.dummyfactory'\n        )\n        route = self._assertRoute(config, 'name', 'path')\n>       self.assertEqual(route.factory, dummyfactory)\nE       AssertionError: <function dummyfactory at 0x7ec39f28e8b0> != <function dummyfactory at 0x7ec39f8193a0>\n\nr2e_tests/test_config/test_routes.py:109: AssertionError\n_____ TestingConfiguratorMixinTests.test_testing_add_subscriber_dottedname _____\n\nself = <r2e_tests.test_config.test_testing.TestingConfiguratorMixinTests testMethod=test_testing_add_subscriber_dottedname>\n\n    def test_testing_add_subscriber_dottedname(self):\n        config = self._makeOne(autocommit=True)\n        L = config.testing_add_subscriber('tests.test_config.IDummy')\n        event = DummyEvent()\n        config.registry.notify(event)\n>       self.assertEqual(len(L), 1)\nE       AssertionError: 0 != 1\n\nr2e_tests/test_config/test_testing.py:108: AssertionError\n____________ TestTweensConfiguratorMixin.test_add_tween_dottedname _____________\n\nself = <r2e_tests.test_config.test_tweens.TestTweensConfiguratorMixin testMethod=test_add_tween_dottedname>\n\n    def test_add_tween_dottedname(self):\n        from pyramid.interfaces import ITweens\n        from pyramid.tweens import excview_tween_factory\n    \n        config = self._makeOne()\n        config.add_tween('tests.test_config.dummy_tween_factory')\n        config.commit()\n        tweens = config.registry.queryUtility(ITweens)\n>       self.assertEqual(\n            tweens.implicit(),\n            [\n                ('tests.test_config.dummy_tween_factory', dummy_tween_factory),\n                (\n                    'pyramid.tweens.excview_tween_factory',\n                    excview_tween_factory,\n                ),\n            ],\n        )\nE       AssertionError: Lists differ: [('te[74 chars]ec39f260670>), ('pyramid.tweens.excview_tween_[57 chars]a0>)] != [('te[74 chars]ec39f819040>), ('pyramid.tweens.excview_tween_[57 chars]a0>)]\nE       \nE       First differing element 0:\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x7ec39f260670>)\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x7ec39f819040>)\nE       \nE         [('tests.test_config.dummy_tween_factory',\nE       -   <function dummy_tween_factory at 0x7ec39f260670>),\nE       ?                                            ^^ ^^\nE       \nE       +   <function dummy_tween_factory at 0x7ec39f819040>),\nE       ?                                            ^^^ ^\nE       \nE          ('pyramid.tweens.excview_tween_factory',\nE           <function excview_tween_factory at 0x7ec39f8a13a0>)]\n\nr2e_tests/test_config/test_tweens.py:105: AssertionError\n__________ TestTweensConfiguratorMixin.test_add_tweens_names_distinct __________\n\nself = <r2e_tests.test_config.test_tweens.TestTweensConfiguratorMixin testMethod=test_add_tweens_names_distinct>\n\n    def test_add_tweens_names_distinct(self):\n        from pyramid.interfaces import ITweens\n        from pyramid.tweens import excview_tween_factory\n    \n        def factory1(handler, registry):  # pragma: no cover\n            return handler\n    \n        def factory2(handler, registry):  # pragma: no cover\n            return handler\n    \n        config = self._makeOne()\n        config.add_tween('tests.test_config.dummy_tween_factory')\n        config.add_tween('tests.test_config.dummy_tween_factory2')\n        config.commit()\n        tweens = config.registry.queryUtility(ITweens)\n        implicit = tweens.implicit()\n>       self.assertEqual(\n            implicit,\n            [\n                (\n                    'tests.test_config.dummy_tween_factory2',\n                    dummy_tween_factory2,\n                ),\n                ('tests.test_config.dummy_tween_factory', dummy_tween_factory),\n                (\n                    'pyramid.tweens.excview_tween_factory',\n                    excview_tween_factory,\n                ),\n            ],\n        )\nE       AssertionError: Lists differ: [('te[76 chars]ec39f260550>), ('tests.test_config.dummy_tween[150 chars]a0>)] != [('te[76 chars]ec39f8190d0>), ('tests.test_config.dummy_tween[150 chars]a0>)]\nE       \nE       First differing element 0:\nE       ('tes[25 chars]n_factory2', <function dummy_tween_factory2 at 0x7ec39f260550>)\nE       ('tes[25 chars]n_factory2', <function dummy_tween_factory2 at 0x7ec39f8190d0>)\nE       \nE         [('tests.test_config.dummy_tween_factory2',\nE       -   <function dummy_tween_factory2 at 0x7ec39f260550>),\nE       ?                                             ^^ ^^\nE       \nE       +   <function dummy_tween_factory2 at 0x7ec39f8190d0>),\nE       ?                                             ^^^ ^\nE       \nE          ('tests.test_config.dummy_tween_factory',\nE       -   <function dummy_tween_factory at 0x7ec39f260670>),\nE       ?                                            ^^ ^^\nE       \nE       +   <function dummy_tween_factory at 0x7ec39f819040>),\nE       ?                                            ^^^ ^\nE       \nE          ('pyramid.tweens.excview_tween_factory',\nE           <function excview_tween_factory at 0x7ec39f8a13a0>)]\n\nr2e_tests/test_config/test_tweens.py:31: AssertionError\n_______ TestTweensConfiguratorMixin.test_add_tweens_names_with_underover _______\n\nself = <r2e_tests.test_config.test_tweens.TestTweensConfiguratorMixin testMethod=test_add_tweens_names_with_underover>\n\n    def test_add_tweens_names_with_underover(self):\n        from pyramid.interfaces import ITweens\n        from pyramid.tweens import MAIN, excview_tween_factory\n    \n        config = self._makeOne()\n        config.add_tween('tests.test_config.dummy_tween_factory', over=MAIN)\n        config.add_tween(\n            'tests.test_config.dummy_tween_factory2',\n            over=MAIN,\n            under='tests.test_config.dummy_tween_factory',\n        )\n        config.commit()\n        tweens = config.registry.queryUtility(ITweens)\n        implicit = tweens.implicit()\n>       self.assertEqual(\n            implicit,\n            [\n                (\n                    'pyramid.tweens.excview_tween_factory',\n                    excview_tween_factory,\n                ),\n                ('tests.test_config.dummy_tween_factory', dummy_tween_factory),\n                (\n                    'tests.test_config.dummy_tween_factory2',\n                    dummy_tween_factory2,\n                ),\n            ],\n        )\nE       AssertionError: Lists differ: [('py[168 chars]ec39f260670>), ('tests.test_config.dummy_tween[58 chars]50>)] != [('py[168 chars]ec39f819040>), ('tests.test_config.dummy_tween[58 chars]d0>)]\nE       \nE       First differing element 1:\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x7ec39f260670>)\nE       ('tes[23 chars]een_factory', <function dummy_tween_factory at 0x7ec39f819040>)\nE       \nE         [('pyramid.tweens.excview_tween_factory',\nE           <function excview_tween_factory at 0x7ec39f8a13a0>),\nE          ('tests.test_config.dummy_tween_factory',\nE       -   <function dummy_tween_factory at 0x7ec39f260670>),\nE       ?                                            ^^ ^^\nE       \nE       +   <function dummy_tween_factory at 0x7ec39f819040>),\nE       ?                                            ^^^ ^\nE       \nE          ('tests.test_config.dummy_tween_factory2',\nE       -   <function dummy_tween_factory2 at 0x7ec39f260550>)]\nE       ?                                             ^^ ^^\nE       \nE       +   <function dummy_tween_factory2 at 0x7ec39f8190d0>)]\nE       ?                                             ^^^ ^\n\nr2e_tests/test_config/test_tweens.py:60: AssertionError\n____ TestViewsConfigurationMixin.test_add_exception_view_with_view_defaults ____\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_exception_view_with_view_defaults>\n\n    def test_add_exception_view_with_view_defaults(self):\n        from zope.interface import directlyProvides, implementedBy\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.renderers import null_renderer\n    \n        class view:\n            __view_defaults__ = {'containment': 'tests.test_config.IDummy'}\n    \n            def __init__(self, request):\n                pass\n    \n            def __call__(self):\n                return 'OK'\n    \n        config = self._makeOne(autocommit=True)\n        config.add_exception_view(\n            view=view, context=Exception, renderer=null_renderer\n        )\n        wrapper = self._getViewCallable(\n            config, exc_iface=implementedBy(Exception)\n        )\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n>       self.assertEqual(wrapper(context, request), 'OK')\n\nr2e_tests/test_config/test_views.py:2494: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x7ec39efec3a0>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x7ec39ef720a0>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view view (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\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 zope.interface import directlyProvides, implementedBy\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPForbidden\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n    \n        class view:\n            __view_defaults__ = {'containment': 'tests.test_config.IDummy'}\n    \n            def __init__(self, request):\n                pass\n    \n            def __call__(self):\n                return 'OK'\n    \n        config = self._makeOne(autocommit=True)\n        config.add_forbidden_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config,\n            exc_iface=implementedBy(HTTPForbidden),\n            request_iface=IRequest,\n        )\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n>       self.assertEqual(wrapper(context, request), 'OK')\n\nr2e_tests/test_config/test_views.py:2722: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x7ec39fe455e0>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x7ec39f18c3d0>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view view (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\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 zope.interface import directlyProvides, implementedBy\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.httpexceptions import HTTPNotFound\n        from pyramid.interfaces import IRequest\n        from pyramid.renderers import null_renderer\n    \n        class view:\n            __view_defaults__ = {'containment': 'tests.test_config.IDummy'}\n    \n            def __init__(self, request):\n                pass\n    \n            def __call__(self):\n                return 'OK'\n    \n        config = self._makeOne(autocommit=True)\n        config.add_notfound_view(view=view, renderer=null_renderer)\n        wrapper = self._getViewCallable(\n            config,\n            exc_iface=implementedBy(HTTPNotFound),\n            request_iface=IRequest,\n        )\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n        request = self._makeRequest(config)\n>       self.assertEqual(wrapper(context, request), 'OK')\n\nr2e_tests/test_config/test_views.py:2890: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x7ec39f20c520>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x7ec39ee467c0>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view view (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\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    \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, [(config, 'static', 'tests.test_config:files', {})]\n        )\nE       AssertionError: Lists differ: [(<py[35 chars] 0x7ec39f0b9550>, 'static', 'r2e_tests.test_config:files', {})] != [(<py[35 chars] 0x7ec39f0b9550>, 'static', 'tests.test_config:files', {})]\nE       \nE       First differing element 0:\nE       (<pyr[33 chars]t 0x7ec39f0b9550>, 'static', 'r2e_tests.test_config:files', {})\nE       (<pyr[33 chars]t 0x7ec39f0b9550>, 'static', 'tests.test_config:files', {})\nE       \nE         [(<pyramid.config.Configurator object at 0x7ec39f0b9550>,\nE           'static',\nE       -   'r2e_tests.test_config:files',\nE       ?    ----\nE       \nE       +   'tests.test_config:files',\nE           {})]\n\nr2e_tests/test_config/test_views.py:2602: AssertionError\n_______ TestViewsConfigurationMixin.test_add_view_context_as_dottedname ________\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_context_as_dottedname>\n\n    def test_add_view_context_as_dottedname(self):\n        from pyramid.renderers import null_renderer\n    \n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            context='tests.test_config.IDummy',\n            view=view,\n            renderer=null_renderer,\n        )\n        wrapper = self._getViewCallable(config, IDummy)\n>       self.assertEqual(wrapper, view)\nE       AssertionError: None != <function TestViewsConfigurationMixin.tes[64 chars]49d0>\n\nr2e_tests/test_config/test_views.py:458: AssertionError\n_________ TestViewsConfigurationMixin.test_add_view_for__as_dottedname _________\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_for__as_dottedname>\n\n    def test_add_view_for__as_dottedname(self):\n        from pyramid.renderers import null_renderer\n    \n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            for_='tests.test_config.IDummy', view=view, renderer=null_renderer\n        )\n        wrapper = self._getViewCallable(config, IDummy)\n>       self.assertEqual(wrapper, view)\nE       AssertionError: None != <function TestViewsConfigurationMixin.tes[61 chars]75e0>\n\nr2e_tests/test_config/test_views.py:469: AssertionError\n____ TestViewsConfigurationMixin.test_add_view_with_containment_dottedname _____\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_containment_dottedname>\n\n    def test_add_view_with_containment_dottedname(self):\n        from zope.interface import directlyProvides\n    \n        from pyramid.renderers import null_renderer\n    \n        view = lambda *arg: 'OK'\n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view=view,\n            containment='tests.test_config.IDummy',\n            renderer=null_renderer,\n        )\n        wrapper = self._getViewCallable(config)\n        context = DummyContext()\n        directlyProvides(context, IDummy)\n>       self.assertEqual(wrapper(context, None), 'OK')\n\nr2e_tests/test_config/test_views.py:1973: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x7ec39f3c1cd0>\nrequest = None\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view <lambda> (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\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.interfaces import ISettings\n        from tests import test_config\n    \n        class view:\n            def __init__(self, context, request):\n                self.request = request\n                self.context = context\n    \n            def __call__(self):\n                return {'a': '1'}\n    \n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = '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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_views.py:1558: 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.interfaces import ISettings\n        from tests import test_config\n    \n        config = self._makeOne(autocommit=True)\n        renderer = self._registerRenderer(config)\n        fixture = '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 'tests.test_config' from '/home/gcpuser/bu[109 chars].py'>\n\nr2e_tests/test_config/test_views.py:1604: AssertionError\n_________ TestViewsConfigurationMixin.test_add_view_with_view_defaults _________\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_view_defaults>\n\n    def test_add_view_with_view_defaults(self):\n        from zope.interface import directlyProvides\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.renderers import null_renderer\n    \n        class view:\n            __view_defaults__ = {'containment': 'tests.test_config.IDummy'}\n    \n            def __init__(self, request):\n                pass\n    \n            def __call__(self):\n                return 'OK'\n    \n        config = self._makeOne(autocommit=True)\n        config.add_view(view=view, 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\nr2e_tests/test_config/test_views.py:2253: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x7ec39eeb5ee0>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x7ec39eeb57c0>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view view (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\n_ TestViewsConfigurationMixin.test_add_view_with_view_defaults_viewname_is_dottedname_kwarg _\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_view_defaults_viewname_is_dottedname_kwarg>\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self):\n        from zope.interface import directlyProvides\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.renderers import null_renderer\n    \n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            view='tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer,\n        )\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\nr2e_tests/test_config/test_views.py:2273: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x7ec39f656160>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x7ec39e9fca00>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view DummyViewDefaultsClass (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\n_ TestViewsConfigurationMixin.test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg _\n\nself = <r2e_tests.test_config.test_views.TestViewsConfigurationMixin testMethod=test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg>\n\n    def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self):\n        from zope.interface import directlyProvides\n    \n        from pyramid.exceptions import PredicateMismatch\n        from pyramid.renderers import null_renderer\n    \n        config = self._makeOne(autocommit=True)\n        config.add_view(\n            'tests.test_config.test_views.DummyViewDefaultsClass',\n            renderer=null_renderer,\n        )\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\nr2e_tests/test_config/test_views.py:2293: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nsrc/pyramid/config/views.py:170: in attr_view\n    return view(context, request)\n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \n\ncontext = <r2e_tests.test_config.test_views.DummyContext object at 0x7ec39ef5c040>\nrequest = <r2e_tests.test_config.test_views.DummyRequest object at 0x7ec39ef86d90>\n\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                )\nE               pyramid.exceptions.PredicateMismatch: predicate mismatch for view DummyViewDefaultsClass (containment = tests.test_config.IDummy)\n\nsrc/pyramid/config/views.py:192: PredicateMismatch\n_________ TestStaticURLInfo.test_generate_url_cachebust_with_overrides _________\n\nself = <r2e_tests.test_config.test_views.TestStaticURLInfo testMethod=test_generate_url_cachebust_with_overrides>\n\n    def test_generate_url_cachebust_with_overrides(self):\n        config = testing.setUp()\n        try:\n            request = testing.DummyRequest()\n            config.add_static_view('static', 'path')\n            config.override_asset(\n                'tests.test_config:path/', 'tests.test_config:other_path/'\n            )\n    \n            def cb(val):\n                def cb_(request, subpath, kw):\n                    kw['_query'] = {'x': val}\n                    return subpath, kw\n    \n                return cb_\n    \n            config.add_cache_buster('path', cb('foo'))\n            result = request.static_url('path/foo.png')\n            self.assertEqual(result, 'http://example.com/static/foo.png?x=foo')\n            config.add_cache_buster('other_path', cb('bar'), explicit=True)\n            result = request.static_url('path/foo.png')\n>           self.assertEqual(result, 'http://example.com/static/foo.png?x=bar')\nE           AssertionError: 'http://example.com/static/foo.png?x=foo' != 'http://example.com/static/foo.png?x=bar'\nE           - http://example.com/static/foo.png?x=foo\nE           ?                                     ^^^\nE           + http://example.com/static/foo.png?x=bar\nE           ?                                     ^^^\n\nr2e_tests/test_config/test_views.py:4085: 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():  # pragma: no cover\n            pass\n    \n        result = self._callFUT(view)\n>       self.assertEqual(result, 'function tests.test_config.test_views.view')\nE       AssertionError: 'function r2e_tests.test_config.test_views.view' != 'function tests.test_config.test_views.view'\nE       - function r2e_tests.test_config.test_views.view\nE       ?          ----\nE       + function tests.test_config.test_views.view\n\nr2e_tests/test_config/test_views.py:4289: AssertionError\n______________________ TestPRoutesCommand.test_class_view ______________________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_class_view>\n\n    def test_class_view(self):\n        from pyramid.renderers import null_renderer as nr\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(\n            route_name='foo',\n            view=dummy.DummyView,\n            attr='view',\n            renderer=nr,\n            request_method='POST',\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.dummy.DummyView.view',\n            'POST',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.dummy.DummyView.view', 'POST'] != ['foo', '/a/b', 'tests.test_scripts.dummy.DummyView.view', 'POST']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.dummy.DummyView.view'\nE       'tests.test_scripts.dummy.DummyView.view'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.dummy.DummyView.view', 'POST']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.dummy.DummyView.view', 'POST']\n\nr2e_tests/test_scripts/test_proutes.py:247: AssertionError\n_________ TestPRoutesCommand.test_one_route_all_methods_view_only_post _________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_one_route_all_methods_view_only_post>\n\n    def test_one_route_all_methods_view_only_post(self):\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(\n            route_name='foo', view=view1, renderer=nr, request_method='POST'\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            'POST',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\n\nr2e_tests/test_scripts/test_proutes.py:362: AssertionError\n_________ TestPRoutesCommand.test_one_route_only_post_view_all_methods _________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_one_route_only_post_view_all_methods>\n\n    def test_one_route_only_post_view_all_methods(self):\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b', request_method='POST')\n        config.add_view(route_name='foo', view=view1, renderer=nr)\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            'POST',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\n\nr2e_tests/test_scripts/test_proutes.py:388: AssertionError\n________ TestPRoutesCommand.test_one_route_only_post_view_post_and_get _________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_one_route_only_post_view_post_and_get>\n\n    def test_one_route_only_post_view_post_and_get(self):\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b', request_method='POST')\n        config.add_view(\n            route_name='foo',\n            view=view1,\n            renderer=nr,\n            request_method=('POST', 'GET'),\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            'POST',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'POST']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'POST']\n\nr2e_tests/test_scripts/test_proutes.py:419: AssertionError\n_____ TestPRoutesCommand.test_one_route_with_long_name_one_view_registered _____\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_one_route_with_long_name_one_view_registered>\n\n    def test_one_route_with_long_name_one_view_registered(self):\n        from zope.interface import Interface\n    \n        from pyramid.interfaces import IRouteRequest, IView, IViewClassifier\n    \n        registry = self._makeRegistry()\n    \n        def view():  # pragma: no cover\n            pass\n    \n        class IMyRoute(Interface):\n            pass\n    \n        registry.registerAdapter(\n            view, (IViewClassifier, IMyRoute, Interface), IView, ''\n        )\n    \n        registry.registerUtility(\n            IMyRoute, IRouteRequest, name='very_long_name_123'\n        )\n    \n        command = self._makeOne()\n        route = dummy.DummyRoute(\n            'very_long_name_123', '/and_very_long_pattern_as_well'\n        )\n        mapper = dummy.DummyMapper(route)\n        command._get_mapper = lambda *arg: mapper\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()[:3]\n>       self.assertEqual(\n            compare_to,\n            [\n                'very_long_name_123',\n                '/and_very_long_pattern_as_well',\n                'tests.test_scripts.test_proutes.view',\n            ],\n        )\nE       AssertionError: Lists differ: ['ver[32 chars]g_pattern_as_well', 'r2e_tests.test_scripts.test_proutes.view'] != ['ver[32 chars]g_pattern_as_well', 'tests.test_scripts.test_proutes.view']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view'\nE       'tests.test_scripts.test_proutes.view'\nE       \nE         ['very_long_name_123',\nE          '/and_very_long_pattern_as_well',\nE       -  'r2e_tests.test_scripts.test_proutes.view']\nE       ?   ----\nE       \nE       +  'tests.test_scripts.test_proutes.view']\n\nr2e_tests/test_scripts/test_proutes.py:211: AssertionError\n______ TestPRoutesCommand.test_route_is_get_view_request_method_not_post _______\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_route_is_get_view_request_method_not_post>\n\n    def test_route_is_get_view_request_method_not_post(self):\n        from pyramid.config import not_\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b', request_method='GET')\n        config.add_view(\n            route_name='foo',\n            view=view1,\n            renderer=nr,\n            request_method=not_('POST'),\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            'GET',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'GET'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'GET']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', 'GET']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', 'GET']\n\nr2e_tests/test_scripts/test_proutes.py:559: AssertionError\n____________ TestPRoutesCommand.test_route_request_method_mismatch _____________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_route_request_method_mismatch>\n\n    def test_route_request_method_mismatch(self):\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b', request_method='POST')\n        config.add_view(\n            route_name='foo', view=view1, renderer=nr, request_method='GET'\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            '<route',\n            'mismatch>',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1[20 chars]ch>'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '[16 chars]ch>']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '<route', 'mismatch>']\nE       - ['foo',\nE       -  '/a/b',\nE       -  'r2e_tests.test_scripts.test_proutes.view1',\nE       -  '<route',\nE       -  'mismatch>']\n\nr2e_tests/test_scripts/test_proutes.py:448: AssertionError\n__________________ TestPRoutesCommand.test_route_static_views __________________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_route_static_views>\n\n    def test_route_static_views(self):\n        config = self._makeConfig(autocommit=True)\n        config.add_static_view('static', 'static', cache_max_age=3600)\n        path2 = os.path.normpath('/var/www/static')\n        config.add_static_view(name='static2', path=path2)\n        config.add_static_view(\n            name='pyramid_scaffold',\n            path='pyramid:scaffolds/starter/+package+/static',\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 5)\n    \n        expected = [\n            [\n                '__static/',\n                '/static/*subpath',\n                'tests.test_scripts:static/',\n                '*',\n            ],\n            ['__static2/', '/static2/*subpath', path2 + os.sep, '*'],\n            [\n                '__pyramid_scaffold/',\n                '/pyramid_scaffold/*subpath',\n                'pyramid:scaffolds/starter/+package+/static/',\n                '*',\n            ],\n        ]\n    \n        for index, line in enumerate(L[2:]):\n            data = line.split()\n>           self.assertEqual(data, expected[index])\nE           AssertionError: Lists differ: ['__static/', '/static/*subpath', 'r2e_tests.test_scripts:static/', '*'] != ['__static/', '/static/*subpath', 'tests.test_scripts:static/', '*']\nE           \nE           First differing element 2:\nE           'r2e_tests.test_scripts:static/'\nE           'tests.test_scripts:static/'\nE           \nE           - ['__static/', '/static/*subpath', 'r2e_tests.test_scripts:static/', '*']\nE           ?                                    ----\nE           \nE           + ['__static/', '/static/*subpath', 'tests.test_scripts:static/', '*']\n\nr2e_tests/test_scripts/test_proutes.py:486: AssertionError\n__________ TestPRoutesCommand.test_single_route_multiview_registered ___________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_single_route_multiview_registered>\n\n    def test_single_route_multiview_registered(self):\n        from zope.interface import Interface\n    \n        from pyramid.interfaces import (\n            IMultiView,\n            IRouteRequest,\n            IViewClassifier,\n        )\n    \n        registry = self._makeRegistry()\n    \n        def view():  # pragma: no cover\n            pass\n    \n        class IMyRoute(Interface):\n            pass\n    \n        multiview1 = dummy.DummyMultiView(\n            view, context='context', view_name='a1'\n        )\n    \n        registry.registerAdapter(\n            multiview1, (IViewClassifier, IMyRoute, Interface), IMultiView, ''\n        )\n        registry.registerUtility(IMyRoute, IRouteRequest, name='a')\n        command = self._makeOne()\n        route = dummy.DummyRoute('a', '/a')\n        mapper = dummy.DummyMapper(route)\n        command._get_mapper = lambda *arg: mapper\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()[:3]\n        view_module = 'tests.test_scripts.dummy'\n        view_str = '<tests.test_scripts.dummy.DummyMultiView'\n        final = '%s.%s' % (view_module, view_str)\n    \n>       self.assertEqual(compare_to, ['a', '/a', final])\nE       AssertionError: Lists differ: ['a', '/a', 'r2e_tests.test_scripts.dummy.<r2e_tests.t[29 chars]iew'] != ['a', '/a', 'tests.test_scripts.dummy.<tests.test_scri[21 chars]iew']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.dummy.<r2e_tests.test_scripts.dummy.DummyMultiView'\nE       'tests.test_scripts.dummy.<tests.test_scripts.dummy.DummyMultiView'\nE       \nE       - ['a',\nE       -  '/a',\nE       -  'r2e_tests.test_scripts.dummy.<r2e_tests.test_scripts.dummy.DummyMultiView']\nE       ? ^ ^^^^                          ----\nE       \nE       + ['a', '/a', 'tests.test_scripts.dummy.<tests.test_scripts.dummy.DummyMultiView']\nE       ? ^ ^^^^^^^^^^^\n\nr2e_tests/test_scripts/test_proutes.py:325: AssertionError\n___________ TestPRoutesCommand.test_single_route_one_view_registered ___________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_single_route_one_view_registered>\n\n    def test_single_route_one_view_registered(self):\n        from zope.interface import Interface\n    \n        from pyramid.interfaces import IRouteRequest, IView, IViewClassifier\n    \n        registry = self._makeRegistry()\n    \n        def view():  # pragma: no cover\n            pass\n    \n        class IMyRoute(Interface):\n            pass\n    \n        registry.registerAdapter(\n            view, (IViewClassifier, IMyRoute, Interface), IView, ''\n        )\n        registry.registerUtility(IMyRoute, IRouteRequest, name='a')\n        command = self._makeOne()\n        route = dummy.DummyRoute('a', '/a')\n        mapper = dummy.DummyMapper(route)\n        command._get_mapper = lambda *arg: mapper\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()[:3]\n>       self.assertEqual(\n            compare_to, ['a', '/a', 'tests.test_scripts.test_proutes.view']\n        )\nE       AssertionError: Lists differ: ['a', '/a', 'r2e_tests.test_scripts.test_proutes.view'] != ['a', '/a', 'tests.test_scripts.test_proutes.view']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view'\nE       'tests.test_scripts.test_proutes.view'\nE       \nE       - ['a', '/a', 'r2e_tests.test_scripts.test_proutes.view']\nE       ?              ----\nE       \nE       + ['a', '/a', 'tests.test_scripts.test_proutes.view']\n\nr2e_tests/test_scripts/test_proutes.py:173: AssertionError\n______________________ TestPRoutesCommand.test_view_glob _______________________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_view_glob>\n\n    def test_view_glob(self):\n        from pyramid.config import not_\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        def view2(context, request):  # pragma: no cover\n            return 'view2'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(\n            route_name='foo',\n            view=view1,\n            renderer=nr,\n            request_method=not_('POST'),\n        )\n    \n        config.add_route('bar', '/b/a')\n        config.add_view(\n            route_name='bar',\n            view=view2,\n            renderer=nr,\n            request_method=not_('POST'),\n        )\n    \n        command = self._makeOne()\n        command.args.glob = '*foo*'\n    \n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            '!POST,*',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', '!POST,*'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '!POST,*']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', '!POST,*']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '!POST,*']\n\nr2e_tests/test_scripts/test_proutes.py:636: AssertionError\n_____________ TestPRoutesCommand.test_view_request_method_not_post _____________\n\nself = <r2e_tests.test_scripts.test_proutes.TestPRoutesCommand testMethod=test_view_request_method_not_post>\n\n    def test_view_request_method_not_post(self):\n        from pyramid.config import not_\n        from pyramid.renderers import null_renderer as nr\n    \n        def view1(context, request):  # pragma: no cover\n            return 'view1'\n    \n        config = self._makeConfig(autocommit=True)\n        config.add_route('foo', '/a/b')\n        config.add_view(\n            route_name='foo',\n            view=view1,\n            renderer=nr,\n            request_method=not_('POST'),\n        )\n    \n        command = self._makeOne()\n        L = []\n        command.out = L.append\n        command.bootstrap = dummy.DummyBootstrap(registry=config.registry)\n        result = command.run()\n        self.assertEqual(result, 0)\n        self.assertEqual(len(L), 3)\n        compare_to = L[-1].split()\n        expected = [\n            'foo',\n            '/a/b',\n            'tests.test_scripts.test_proutes.view1',\n            '!POST,*',\n        ]\n>       self.assertEqual(compare_to, expected)\nE       AssertionError: Lists differ: ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', '!POST,*'] != ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '!POST,*']\nE       \nE       First differing element 2:\nE       'r2e_tests.test_scripts.test_proutes.view1'\nE       'tests.test_scripts.test_proutes.view1'\nE       \nE       - ['foo', '/a/b', 'r2e_tests.test_scripts.test_proutes.view1', '!POST,*']\nE       ?                  ----\nE       \nE       + ['foo', '/a/b', 'tests.test_scripts.test_proutes.view1', '!POST,*']\n\nr2e_tests/test_scripts/test_proutes.py:591: AssertionError\n_____________ TestPServeCommand.test_config_file_finds_watch_files _____________\n\nself = <r2e_tests.test_scripts.test_pserve.TestPServeCommand testMethod=test_config_file_finds_watch_files>\n\n    def test_config_file_finds_watch_files(self):\n        inst = self._makeOne('development.ini')\n        loader = self.loader('/base/path.ini')\n        loader.settings = {\n            'pserve': {'watch_files': 'foo\\n/baz\\ntests.test_scripts:*.py'}\n        }\n        inst.pserve_file_config(loader, global_conf={'a': '1'})\n        self.assertEqual(loader.calls[0]['defaults'], {'a': '1'})\n>       self.assertEqual(\n            inst.watch_files,\n            {\n                os.path.abspath('/base/foo'),\n                os.path.abspath('/baz'),\n                os.path.abspath(os.path.join(here, '*.py')),\n            },\n        )\nE       AssertionError: Items in the first set but not the second:\nE       '/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/tests/test_scripts/*.py'\nE       Items in the second set but not the first:\nE       '/home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_scripts/*.py'\n\nr2e_tests/test_scripts/test_pserve.py:90: AssertionError\n____________ TestPViewsCommand.test_views_command_multi_view_nested ____________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_multi_view_nested>\n\n    def test_views_command_multi_view_nested(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        view1 = dummy.DummyView(context='context', view_name='a1')\n        view1.__name__ = 'view1'\n        view1.__view_attr__ = 'call'\n        multiview1 = dummy.DummyMultiView(\n            view1, context='context', view_name='a1'\n        )\n        multiview2 = dummy.DummyMultiView(\n            multiview1, context='context', view_name='a'\n        )\n        command._find_view = lambda arg1: multiview2\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.DummyMultiView')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.DummyMultiView' != '    tests.test_scripts.dummy.DummyMultiView'\nE       -     r2e_tests.test_scripts.dummy.DummyMultiView\nE       ?     ----\nE       +     tests.test_scripts.dummy.DummyMultiView\n\nr2e_tests/test_scripts/test_pviews.py:475: AssertionError\n________________ TestPViewsCommand.test_views_command_multiview ________________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_multiview>\n\n    def test_views_command_multiview(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        view = dummy.DummyView(context='context')\n        view.__name__ = 'view'\n        view.__view_attr__ = 'call'\n        multiview = dummy.DummyMultiView(\n            view, context='context', view_name='a'\n        )\n        command._find_view = lambda arg1: multiview\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.view.call')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.view.call' != '    tests.test_scripts.dummy.view.call'\nE       -     r2e_tests.test_scripts.dummy.view.call\nE       ?     ----\nE       +     tests.test_scripts.dummy.view.call\n\nr2e_tests/test_scripts/test_pviews.py:531: AssertionError\n________ TestPViewsCommand.test_views_command_multiview_with_permission ________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_multiview_with_permission>\n\n    def test_views_command_multiview_with_permission(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        view = dummy.DummyView(context='context')\n        view.__name__ = 'view'\n        view.__view_attr__ = 'call'\n        view.__permission__ = 'test'\n        multiview = dummy.DummyMultiView(\n            view, context='context', view_name='a'\n        )\n        command._find_view = lambda arg1: multiview\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.view.call')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.view.call' != '    tests.test_scripts.dummy.view.call'\nE       -     r2e_tests.test_scripts.dummy.view.call\nE       ?     ----\nE       +     tests.test_scripts.dummy.view.call\n\nr2e_tests/test_scripts/test_pviews.py:555: AssertionError\n________ TestPViewsCommand.test_views_command_multiview_with_predicates ________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_multiview_with_predicates>\n\n    def test_views_command_multiview_with_predicates(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n    \n        def predicate():  # pragma: no cover\n            pass\n    \n        predicate.text = lambda *arg: \"predicate = x\"\n        view = dummy.DummyView(context='context')\n        view.__name__ = 'view'\n        view.__view_attr__ = 'call'\n        view.__predicates__ = [predicate]\n        multiview = dummy.DummyMultiView(\n            view, context='context', view_name='a'\n        )\n        command._find_view = lambda arg1: multiview\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.view.call')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.view.call' != '    tests.test_scripts.dummy.view.call'\nE       -     r2e_tests.test_scripts.dummy.view.call\nE       ?     ----\nE       +     tests.test_scripts.dummy.view.call\n\nr2e_tests/test_scripts/test_pviews.py:585: 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    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n    \n        def view():  # pragma: no cover\n            pass\n    \n        view.__request_attrs__ = {'context': 'context', 'view_name': 'a'}\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.test_pviews.view')\nE       AssertionError: '    r2e_tests.test_scripts.test_pviews.view' != '    tests.test_scripts.test_pviews.view'\nE       -     r2e_tests.test_scripts.test_pviews.view\nE       ?     ----\nE       +     tests.test_scripts.test_pviews.view\n\nr2e_tests/test_scripts/test_pviews.py:378: AssertionError\n____________ TestPViewsCommand.test_views_command_single_view_route ____________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_route>\n\n    def test_views_command_single_view_route(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        route = dummy.DummyRoute('a', '/a', matchdict={})\n        view = dummy.DummyView(\n            context='context', view_name='a', matched_route=route, subpath=''\n        )\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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[6], '    Route:')\n        self.assertEqual(L[8], '    route name: a')\n        self.assertEqual(L[9], '    route pattern: /a')\n        self.assertEqual(L[10], '    route path: /a')\n        self.assertEqual(L[11], '    subpath: ')\n>       self.assertEqual(L[15], '        tests.test_scripts.dummy.DummyView')\nE       AssertionError: '        r2e_tests.test_scripts.dummy.DummyView' != '        tests.test_scripts.dummy.DummyView'\nE       -         r2e_tests.test_scripts.dummy.DummyView\nE       ?         ----\nE       +         tests.test_scripts.dummy.DummyView\n\nr2e_tests/test_scripts/test_pviews.py:449: AssertionError\n_ TestPViewsCommand.test_views_command_single_view_route_with_route_predicates _\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_route_with_route_predicates>\n\n    def test_views_command_single_view_route_with_route_predicates(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n    \n        def predicate():  # pragma: no cover\n            pass\n    \n        predicate.text = lambda *arg: \"predicate = x\"\n        route = dummy.DummyRoute('a', '/a', matchdict={}, predicate=predicate)\n        view = dummy.DummyView(\n            context='context', view_name='a', matched_route=route, subpath=''\n        )\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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[6], '    Route:')\n        self.assertEqual(L[8], '    route name: a')\n        self.assertEqual(L[9], '    route pattern: /a')\n        self.assertEqual(L[10], '    route path: /a')\n        self.assertEqual(L[11], '    subpath: ')\n        self.assertEqual(L[12], '    route predicates (predicate = x)')\n>       self.assertEqual(L[16], '        tests.test_scripts.dummy.DummyView')\nE       AssertionError: '        r2e_tests.test_scripts.dummy.DummyView' != '        tests.test_scripts.dummy.DummyView'\nE       -         r2e_tests.test_scripts.dummy.DummyView\nE       ?         ----\nE       +         tests.test_scripts.dummy.DummyView\n\nr2e_tests/test_scripts/test_pviews.py:508: AssertionError\n__________ TestPViewsCommand.test_views_command_single_view_traversal __________\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_traversal>\n\n    def test_views_command_single_view_traversal(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        view = dummy.DummyView(context='context', view_name='a')\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.DummyView')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.DummyView' != '    tests.test_scripts.dummy.DummyView'\nE       -     r2e_tests.test_scripts.dummy.DummyView\nE       ?     ----\nE       +     tests.test_scripts.dummy.DummyView\n\nr2e_tests/test_scripts/test_pviews.py:356: AssertionError\n__ TestPViewsCommand.test_views_command_single_view_traversal_with_permission __\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_traversal_with_permission>\n\n    def test_views_command_single_view_traversal_with_permission(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n        view = dummy.DummyView(context='context', view_name='a')\n        view.__permission__ = 'test'\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.DummyView')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.DummyView' != '    tests.test_scripts.dummy.DummyView'\nE       -     r2e_tests.test_scripts.dummy.DummyView\nE       ?     ----\nE       +     tests.test_scripts.dummy.DummyView\n\nr2e_tests/test_scripts/test_pviews.py:397: AssertionError\n__ TestPViewsCommand.test_views_command_single_view_traversal_with_predicates __\n\nself = <r2e_tests.test_scripts.test_pviews.TestPViewsCommand testMethod=test_views_command_single_view_traversal_with_predicates>\n\n    def test_views_command_single_view_traversal_with_predicates(self):\n        from pyramid.registry import Registry\n    \n        registry = Registry()\n        command = self._makeOne(registry=registry)\n        L = []\n        command.out = L.append\n    \n        def predicate():  # pragma: no cover\n            pass\n    \n        predicate.text = lambda *arg: \"predicate = x\"\n        view = dummy.DummyView(context='context', view_name='a')\n        view.__predicates__ = [predicate]\n        command._find_view = lambda arg1: view\n        command.args.config_uri = '/foo/bar/myapp.ini#myapp'\n        command.args.url = '/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], '    tests.test_scripts.dummy.DummyView')\nE       AssertionError: '    r2e_tests.test_scripts.dummy.DummyView' != '    tests.test_scripts.dummy.DummyView'\nE       -     r2e_tests.test_scripts.dummy.DummyView\nE       ?     ----\nE       +     tests.test_scripts.dummy.DummyView\n\nr2e_tests/test_scripts/test_pviews.py:422: AssertionError\n=============================== warnings summary ===============================\nsrc/pyramid/asset.py:2\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/src/pyramid/asset.py:2: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html\n    import pkg_resources\n\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('paste')`.\n  Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages\n    declare_namespace(pkg)\n\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/.venv/lib/python3.8/site-packages/pkg_resources/__init__.py:3154: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('zope')`.\n  Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages\n    declare_namespace(pkg)\n\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_authentication_policy\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_authorization_policy_only\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy_dottedname\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authorization_policy_dottedname\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authorization_policy_only\nr2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_no_default_permission_no_explicit_permission\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/src/pyramid/config/__init__.py:405: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    self.set_authorization_policy(authorization_policy)\n\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_ctor_authentication_policy\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authentication_policy_dottedname\nr2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_authorization_policy_dottedname\nr2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_no_default_permission_no_explicit_permission\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/src/pyramid/config/__init__.py:408: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    self.set_authentication_policy(authentication_policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_no_authz_policy\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:37: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authentication_policy(policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_no_authz_policy_autocommit\n  /home/gcpuser/.local/share/uv/python/cpython-3.8.20-linux-x86_64-gnu/lib/python3.8/unittest/case.py:202: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    callable_obj(*args, **kwargs)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_with_authz_policy\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:59: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authentication_policy(authn_policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_with_authz_policy_autocommit\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:80: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authentication_policy(authn_policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authentication_policy_with_security_policy\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:31: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authentication_policy(authn_policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_no_authn_policy\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:92: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authorization_policy(policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_no_authn_policy_autocommit\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:100: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authorization_policy(policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_with_authn_policy\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:115: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authorization_policy(authz_policy)\n\nr2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_authorization_policy_with_authn_policy_autocommit\n  /home/gcpuser/buckets/local_repoeval_bucket/repos/pyramid_68c84ae5aa2898251a07455e958fd0a11926d114/r2e_tests/test_config/test_security.py:131: DeprecationWarning: Authentication and authorization policies have been deprecated in favor of security policies.  See \"Upgrading Authentication/Authorization\" in \"What's New in Pyramid 2.0\" of the documentation for more information.\n    config.set_authorization_policy(authz_policy)\n\n-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n==================================== PASSES ====================================\n=========================== short test summary info ============================\nPASSED r2e_tests/test_1.py::TestRouter::test_call_eventsends\nPASSED r2e_tests/test_1.py::TestRouter::test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview\nPASSED r2e_tests/test_1.py::TestRouter::test_call_no_view_registered_debug_notfound_false\nPASSED r2e_tests/test_1.py::TestRouter::test_call_no_view_registered_debug_notfound_true\nPASSED r2e_tests/test_1.py::TestRouter::test_call_no_view_registered_no_isettings\nPASSED r2e_tests/test_1.py::TestRouter::test_call_request_factory_raises\nPASSED r2e_tests/test_1.py::TestRouter::test_call_request_has_response_callbacks\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_match_miss_debug_routematch\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_matches_and_has_factory\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_matches_doesnt_overwrite_subscriber_iface\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_exception_another_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_exception_view_another_route\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_exception_view_specializing\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_route_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_sub_exception_super_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_route_raises_super_exception_sub_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_traverser_default\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_exception_propagating\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_multiple_predicate_mismatches_dont_hide_views\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_predicate_mismatch_doesnt_find_unrelated_views\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_predicate_mismatch_doesnt_hide_views\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_exception_another_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_exception_route_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_exception_view_route\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_forbidden\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_notfound\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_predicate_mismatch\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_response_cleared\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_sub_exception_super_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_raises_super_exception_sub_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_registered_nonspecific_default_path\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_registered_nonspecific_nondefault_path_and_subpath\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_registered_specific_fail\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_registered_specific_success\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_returns_adapted_response\nPASSED r2e_tests/test_1.py::TestRouter::test_call_view_returns_non_iresponse\nPASSED r2e_tests/test_1.py::TestRouter::test_call_with_request_extensions\nPASSED r2e_tests/test_1.py::TestRouter::test_ctor_registry_has_no_settings\nPASSED r2e_tests/test_1.py::TestRouter::test_custom_execution_policy\nPASSED r2e_tests/test_1.py::TestRouter::test_exception_view_returns_non_iresponse\nPASSED r2e_tests/test_1.py::TestRouter::test_execution_policy_bubbles_exception\nPASSED r2e_tests/test_1.py::TestRouter::test_request_context_manually\nPASSED r2e_tests/test_1.py::TestRouter::test_request_context_with_statement\nPASSED r2e_tests/test_1.py::TestRouter::test_request_factory\nPASSED r2e_tests/test_1.py::TestRouter::test_root_factory_exception_propagating\nPASSED r2e_tests/test_1.py::TestRouter::test_root_factory_raises_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_root_factory_raises_forbidden\nPASSED r2e_tests/test_1.py::TestRouter::test_root_factory_raises_notfound\nPASSED r2e_tests/test_1.py::TestRouter::test_root_policy\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_exception_propagating\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_raises_exception_view\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_raises_forbidden_class\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_raises_forbidden_instance\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_raises_notfound_class\nPASSED r2e_tests/test_1.py::TestRouter::test_traverser_raises_notfound_instance\nPASSED r2e_tests/test_1.py::TestRouter::test_tween_factories\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_autocommit_with_introspectables\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_autocommit_with_introspectables_introspection_off\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_branching_kw_is_None\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_branching_kw_is_not_None\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_branching_nonautocommit_with_config_info\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_branching_nonautocommit_with_introspectables\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_branching_nonautocommit_without_config_info\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_action_nonautocommit_with_introspectables_introspection_off\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_autocommit_no_conflicts\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_commit_conflict_resolved_with_include\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_commit_conflict_resolved_with_two_includes_and_local\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_commit_conflict_simple\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_commit_conflict_with_two_includes\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_conflict_set_forbidden_view\nPASSED r2e_tests/test_config/test_actions.py::ActionConfiguratorMixinTests::test_conflict_set_notfound_view\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_simple\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_with_includepath\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_with_includepath_and_info\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_with_info\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_with_introspectables\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_action_with_order\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_execute_actions_dicts\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_execute_actions_error\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_execute_actions_tuples\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_execute_actions_with_introspectable_no_callable\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_execute_actions_with_introspectables\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_executing_conflicting_action_across_orders\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_executing_conflicting_action_across_reentrant_orders\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_it\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_processSpec\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_reentrant_action\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_reentrant_action_error\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_reentrant_action_with_deferred_discriminator\nPASSED r2e_tests/test_config/test_actions.py::TestActionState::test_reentrant_action_without_clear\nPASSED r2e_tests/test_config/test_actions.py::Test_reentrant_action_functional::test_deferred_discriminator\nPASSED r2e_tests/test_config/test_actions.py::Test_reentrant_action_functional::test_functional\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_conflicts_across_orders\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_it_conflict\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_it_success_dicts\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_it_success_tuples\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_it_with_actions_grouped_by_order\nPASSED r2e_tests/test_config/test_actions.py::Test_resolveConflicts::test_override_success_across_orders\nPASSED r2e_tests/test_config/test_actions.py::TestActionInfo::test___str__\nPASSED r2e_tests/test_config/test_actions.py::TestActionInfo::test_class_conforms\nPASSED r2e_tests/test_config/test_actions.py::TestActionInfo::test_ctor\nPASSED r2e_tests/test_config/test_actions.py::TestActionInfo::test_instance_conforms\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_absdirectory\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_directory_with_absfile\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_file_with_absdirectory\nPASSED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_file_with_absfile\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_missing_abspath\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_absdirectory\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_filtered_sources\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\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::TestPackageAssetSource::test_exists\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_exists_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_exists_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_filename_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_stream\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_stream_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_stream_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_string\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_string_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_string_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_isdir_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_isdir_false\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_isdir_true\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_listdir\nPASSED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_listdir_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_exists\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_exists_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_exists_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_filename\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_filename_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_filename_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_stream\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_stream_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_stream_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_string\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_string_file_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_get_string_with_prefix\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_isdir_doesnt_exist\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_isdir_false\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_isdir_true\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_listdir\nPASSED r2e_tests/test_config/test_assets.py::TestFSAssetSource::test_listdir_doesnt_exist\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_text_name\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_execution_policy\nPASSED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_execution_policy_to_None\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_response_factory\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_session_factory\nPASSED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_invalid_kwargs\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_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_adds__lock\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test__fix_registry_adds_clear_view_lookup_cache\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_begin\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin_does_not_propagate_request_for_diff_registry\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin_overrides_request\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin_propagates_request_for_same_registry\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_begin_with_request\nPASSED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_context_manager\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_security_policy\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_threadlocals_active\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_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_conflict\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_response_factory\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_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::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::TestPredicateList::test_custom_predicates_can_affect_traversal\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_different_custom_predicates_with_same_hash\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple_mixed\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple_mixed_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple_with_values\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_multiple_with_values_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_simple\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_simple_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_with_value\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_with_value_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_header_with_value_fails_case\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_is_authenticated_false_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_is_authenticated_false_matches\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_is_authenticated_true_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_is_authenticated_true_matches\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_match_param_from_dict\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_match_param_from_dict_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_match_param_from_string\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_match_param_from_string_fails\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_notted\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_ordering_importance_and_number\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_ordering_importance_of_predicates\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_ordering_number_of_predicates\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_ordering_xhr_and_request_method_trump_only_containment\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_predicate_close_matches\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_predicate_text_is_correct\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_predicate_text_is_correct_when_multiple\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_request_method_ordering_hashes_same\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_request_method_sequence\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_traverse_has_remainder_already\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_traverse_matches\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_traverse_matches_with_highorder_chars\nPASSED r2e_tests/test_config/test_predicates.py::TestPredicateList::test_unknown_predicate\nPASSED r2e_tests/test_config/test_predicates.py::Test_sort_accept_offers::test_default_specificities\nPASSED r2e_tests/test_config/test_predicates.py::Test_sort_accept_offers::test_params_inherit_type_prefs\nPASSED r2e_tests/test_config/test_predicates.py::Test_sort_accept_offers::test_params_order\nPASSED r2e_tests/test_config/test_predicates.py::Test_sort_accept_offers::test_specific_type_order\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_effective_principals_deprecated\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_accept_list\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_header\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_inherit_errors\nPASSED r2e_tests/test_config/test_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_is_authenticated\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_root_slash_with_route_prefix\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_route_prefix_with_inherit_slash\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_wildcard_accept_raises\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_changing_set_default_csrf_options\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_authentication_policy_with_security_policy\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_csrf_options\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_default_permission\nPASSED r2e_tests/test_config/test_security.py::ConfiguratorSecurityMethodsTests::test_set_security_policy\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__set_settings_does_not_uses_original_dict\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::TestSettingsConfiguratorMixin::test_settings_parameter_dict_is_never_updated\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_csrf_trusted_origins\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_noargs\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_originals_kept\nPASSED r2e_tests/test_config/test_settings.py::TestSettings::test_prevent_cachebust\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_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_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_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::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_views.py::TestViewsConfigurationMixin::test_add_accept_view_order_override\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_accept_view_order_throws_on_type_mismatch\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_accept_view_order_throws_on_wildcard\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_disallows_exception_only\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_disallows_for_\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_disallows_name\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_disallows_permission\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_disallows_require_csrf\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_with_subclass\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_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_disallows_require_csrf\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_forbidden_view_no_view_argument\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_normal_and_exception_view_intr_derived_callable\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_append_slash_custom_response\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_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_disallows_require_csrf\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_notfound_view_no_view_argument\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_class_method_no_attr\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_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_custom_predicate_bests_standard_predicate\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_does_not_accept_iterable_accept\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_multiviews\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exc_multiview_replaces_only_exc_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_only\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exception_only_misconfiguration\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_exception_only_no_regular_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_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_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_csrf_header\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_csrf_param\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_custom_predicates_nomatch\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_is_authenticated_false_matches\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_is_authenticated_false_no_match\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_is_authenticated_true_matches\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_is_authenticated_true_no_match\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_missing_csrf_header\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_wildcard_accept_raises\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_default_accept_view_order\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_effective_principals_deprecated\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::TestViewsConfigurationMixin::test_view_with_most_specific_predicate\nPASSED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_view_with_most_specific_predicate_with_mismatch\nPASSED r2e_tests/test_config/test_views.py::Test_runtime_exc_view::test_call\nPASSED r2e_tests/test_config/test_views.py::Test_runtime_exc_view::test_call_dispatches_on_exception\nPASSED r2e_tests/test_config/test_views.py::Test_runtime_exc_view::test_permitted\nPASSED r2e_tests/test_config/test_views.py::Test_runtime_exc_view::test_permitted_dispatches_on_exception\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::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_cachebust_prevented\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_cachebuster\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_cachebuster_abspath\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_cachebuster_for_more_specific_path\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_cachebuster_overwrite\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_cachebuster_overwrite_explicit\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_add_package_root\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_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_cachebust\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_cachebust_abspath\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_cachebust_nomatch\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_generate_url_with_custom_anchor\nPASSED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_with_custom_query\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_config/test_views.py::Test_viewdefaults::test_dunder_attrs_copied\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_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_display_headers\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_has_content_type_header_var\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_good_header_var\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_has_multiple_header_vars\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_configures_logging\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_get\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_options\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_patch\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_post\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_propfind\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_method_put\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_path_doesnt_start_with_slash\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_response_has_no_charset\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_two_args\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_w_basic_auth\nPASSED r2e_tests/test_scripts/test_prequest.py::TestPRequestCommand::test_command_with_query_string\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_bad_format\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_config_format_ini_commas\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_config_format_ini_newlines\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_config_format_ini_spaces\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_good_args\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_good_format\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_as_wsgiapp\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_route_no_view\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_with_factory\nPASSED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_static_routes_included_in_list\nPASSED r2e_tests/test_scripts/test_proutes.py::Test_main::test_it\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_config_file_finds_open_url\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_guess_server_url\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_original_ignore_files\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_reload_call_hupper_with_correct_args\nPASSED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_run_no_args\nPASSED r2e_tests/test_scripts/test_pserve.py::Test_main::test_it\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_default_shell_option\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_errors_with_unknown_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_ipython\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_command_loads_pythonstartup\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_command_setup_generator\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_list_shells\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_shell_entry_points\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_shell_ordering\nPASSED r2e_tests/test_scripts/test_pshell.py::TestPShellCommand::test_shell_override\nPASSED r2e_tests/test_scripts/test_pshell.py::Test_python_shell_runner::test_it\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_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::Test_main::test_it\nFAILED r2e_tests/test_1.py::TestRouter::test_finish_request_when_view_raises\nFAILED r2e_tests/test_1.py::TestRouter::test_finish_request_when_view_succeeds\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::TestAssetsConfiguratorMixin::test_override_asset_directory_with_directory\nFAILED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_directory_with_package\nFAILED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_file_with_file\nFAILED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_package_with_directory\nFAILED r2e_tests/test_config/test_assets.py::TestAssetsConfiguratorMixin::test_override_asset_package_with_package\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::TestPackageAssetSource::test_get_filename\nFAILED r2e_tests/test_config/test_assets.py::TestPackageAssetSource::test_get_filename_with_prefix\nFAILED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_request_factory_dottedname\nFAILED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_response_factory_dottedname\nFAILED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_root_factory_dottedname\nFAILED r2e_tests/test_config/test_factories.py::TestFactoriesMixin::test_set_session_factory_dottedname\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_doesnt_use_override_w_autocommit\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_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_override_multiple_specs_multiple_calls\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_uses_override_out_of_order\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_add_translation_dirs_uses_override_w_autocommit\nFAILED r2e_tests/test_config/test_i18n.py::TestI18NConfiguratorMixin::test_set_locale_negotiator_dottedname\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_include_constant_root_package\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_include_with_python_callable\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_debug_logger_None_default\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_setup_registry_tweens\nFAILED r2e_tests/test_config/test_init.py::ConfiguratorTests::test_with_package_module\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_routes.py::RoutesConfiguratorMixinTests::test_add_route_with_factory_dottedname\nFAILED r2e_tests/test_config/test_testing.py::TestingConfiguratorMixinTests::test_testing_add_subscriber_dottedname\nFAILED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tween_dottedname\nFAILED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_distinct\nFAILED r2e_tests/test_config/test_tweens.py::TestTweensConfiguratorMixin::test_add_tweens_names_with_underover\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_exception_view_with_view_defaults\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_context_as_dottedname\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_for__as_dottedname\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_containment_dottedname\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::TestViewsConfigurationMixin::test_add_view_with_view_defaults\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_kwarg\nFAILED r2e_tests/test_config/test_views.py::TestViewsConfigurationMixin::test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg\nFAILED r2e_tests/test_config/test_views.py::TestStaticURLInfo::test_generate_url_cachebust_with_overrides\nFAILED r2e_tests/test_config/test_views.py::Test_view_description::test_without_text\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_class_view\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_one_route_all_methods_view_only_post\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_one_route_only_post_view_all_methods\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_one_route_only_post_view_post_and_get\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_one_route_with_long_name_one_view_registered\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_route_is_get_view_request_method_not_post\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_route_request_method_mismatch\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_route_static_views\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_multiview_registered\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_single_route_one_view_registered\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_view_glob\nFAILED r2e_tests/test_scripts/test_proutes.py::TestPRoutesCommand::test_view_request_method_not_post\nFAILED r2e_tests/test_scripts/test_pserve.py::TestPServeCommand::test_config_file_finds_watch_files\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multi_view_nested\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview_with_permission\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_multiview_with_predicates\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_function_traversal\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_route\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_route_with_route_predicates\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal_with_permission\nFAILED r2e_tests/test_scripts/test_pviews.py::TestPViewsCommand::test_views_command_single_view_traversal_with_predicates\n================= 82 failed, 803 passed, 28 warnings in 5.58s ==================\n",
    "old_commit_res_stderr": ""
}
CHANGES.rst src/pyramid/router.py tests/test_router.py
We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ISSUE]
**Title:** Reference Cycle Caused by Unremoved `context` in Request Object

**Description:**
After processing a request, the `request` object retains a reference to the `context`. This prevents the garbage collector from reclaiming memory, leading to reference cycles and potential memory leaks in long-running applications.

**Example:**
```python
def handle_request():
    request = Request()
    context = Context()
    request.context = context

    def view(context, request):
        request.add_finished_callback(lambda req: None)
        return Response('OK')

    router = Router()
    router.process(request, view)

    # After processing, 'context' should be removed
    assert not hasattr(request, 'context')
```

**Expected Behavior:**
After the request is processed, the `context` attribute should be removed from the `request` object to break the reference cycle, allowing proper garbage collection.

**Actual Behavior:**
The `context` attribute remains on the `request` object, maintaining a reference cycle and preventing garbage collection.
[/ISSUE]
--- END ISSUE ---

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

--- BEGIN FILE ---
```
### src/pyramid/router.py
from zope.interface import implementer, providedBy

from pyramid.events import (
    BeforeTraversal,
    ContextFound,
    NewRequest,
    NewResponse,
)
from pyramid.httpexceptions import HTTPNotFound
from pyramid.interfaces import (
    IDebugLogger,
    IExecutionPolicy,
    IRequest,
    IRequestExtensions,
    IRequestFactory,
    IRootFactory,
    IRouter,
    IRouteRequest,
    IRoutesMapper,
    ITraverser,
    ITweens,
)
from pyramid.request import Request, apply_request_extensions
from pyramid.threadlocal import RequestContext
from pyramid.traversal import DefaultRootFactory, ResourceTreeTraverser
from pyramid.view import _call_view


@implementer(IRouter)
class Router:

    debug_notfound = False
    debug_routematch = False

    def __init__(self, registry):
        q = registry.queryUtility
        self.logger = q(IDebugLogger)
        self.root_factory = q(IRootFactory, default=DefaultRootFactory)
        self.routes_mapper = q(IRoutesMapper)
        self.request_factory = q(IRequestFactory, default=Request)
        self.request_extensions = q(IRequestExtensions)
        self.execution_policy = q(
            IExecutionPolicy, default=default_execution_policy
        )
        self.orig_handle_request = self.handle_request
        tweens = q(ITweens)
        if tweens is not None:
            self.handle_request = tweens(self.handle_request, registry)
        self.root_policy = self.root_factory  # b/w compat
        self.registry = registry
        settings = registry.settings
        if settings is not None:
            self.debug_notfound = settings['debug_notfound']
            self.debug_routematch = settings['debug_routematch']

    def handle_request(self, request):
        attrs = request.__dict__
        registry = attrs['registry']

        request.request_iface = IRequest
        context = None
        routes_mapper = self.routes_mapper
        debug_routematch = self.debug_routematch
        adapters = registry.adapters
        has_listeners = registry.has_listeners
        notify = registry.notify
        logger = self.logger

        has_listeners and notify(NewRequest(request))
        # find the root object
        root_factory = self.root_factory
        if routes_mapper is not None:
            info = routes_mapper(request)
            match, route = info['match'], info['route']
            if route is None:
                if debug_routematch:
                    msg = 'no route matched for url %s' % request.url
                    logger and logger.debug(msg)
            else:
                attrs['matchdict'] = match
                attrs['matched_route'] = route

                if debug_routematch:
                    msg = (
                        'route matched for url %s; '
                        'route_name: %r, '
                        'path_info: %r, '
                        'pattern: %r, '
                        'matchdict: %r, '
                        'predicates: %r'
                        % (
                            request.url,
                            route.name,
                            request.path_info,
                            route.pattern,
                            match,
                            ', '.join([p.text() for p in route.predicates]),
                        )
                    )
                    logger and logger.debug(msg)

                request.request_iface = registry.queryUtility(
                    IRouteRequest, name=route.name, default=IRequest
                )

                root_factory = route.factory or self.root_factory

        # Notify anyone listening that we are about to start traversal
        #
        # Notify before creating root_factory in case we want to do something
        # special on a route we may have matched. See
        # https://github.com/Pylons/pyramid/pull/1876 for ideas of what is
        # possible.
        has_listeners and notify(BeforeTraversal(request))

        # Create the root factory
        root = root_factory(request)
        attrs['root'] = root

        # We are about to traverse and find a context
        traverser = adapters.queryAdapter(root, ITraverser)
        if traverser is None:
            traverser = ResourceTreeTraverser(root)
        tdict = traverser(request)

        context, view_name, subpath, traversed, vroot, vroot_path = (
            tdict['context'],
            tdict['view_name'],
            tdict['subpath'],
            tdict['traversed'],
            tdict['virtual_root'],
            tdict['virtual_root_path'],
        )

        attrs.update(tdict)

        # Notify anyone listening that we have a context and traversal is
        # complete
        has_listeners and notify(ContextFound(request))

        # find a view callable
        context_iface = providedBy(context)
        response = _call_view(
            registry, request, context, context_iface, view_name
        )

        if response is None:
            if self.debug_notfound:
                msg = (
                    'debug_notfound of url %s; path_info: %r, '
                    'context: %r, view_name: %r, subpath: %r, '
                    'traversed: %r, root: %r, vroot: %r, '
                    'vroot_path: %r'
                    % (
                        request.url,
                        request.path_info,
                        context,
                        view_name,
                        subpath,
                        traversed,
                        root,
                        vroot,
                        vroot_path,
                    )
                )
                logger and logger.debug(msg)
            else:
                msg = request.path_info
            raise HTTPNotFound(msg)

        return response

    def invoke_subrequest(self, request, use_tweens=False):
        """Obtain a response object from the Pyramid application based on
        information in the ``request`` object provided.  The ``request``
        object must be an object that implements the Pyramid request
        interface (such as a :class:`pyramid.request.Request` instance).  If
        ``use_tweens`` is ``True``, the request will be sent to the
        :term:`tween` in the tween stack closest to the request ingress.  If
        ``use_tweens`` is ``False``, the request will be sent to the main
        router handler, and no tweens will be invoked.

        See the API for pyramid.request for complete documentation.
        """
        request.registry = self.registry
        request.invoke_subrequest = self.invoke_subrequest
        extensions = self.request_extensions
        if extensions is not None:
            apply_request_extensions(request, extensions=extensions)
        with RequestContext(request):
            return self.invoke_request(request, _use_tweens=use_tweens)

    def request_context(self, environ):
        """
        Create a new request context from a WSGI environ.

        The request context is used to push/pop the threadlocals required
        when processing the request. It also contains an initialized
        :class:`pyramid.interfaces.IRequest` instance using the registered
        :class:`pyramid.interfaces.IRequestFactory`. The context may be
        used as a context manager to control the threadlocal lifecycle:

        .. code-block:: python

            with router.request_context(environ) as request:
                ...

        Alternatively, the context may be used without the ``with`` statement
        by manually invoking its ``begin()`` and ``end()`` methods.

        .. code-block:: python

            ctx = router.request_context(environ)
            request = ctx.begin()
            try:
                ...
            finally:
                ctx.end()

        """
        request = self.request_factory(environ)
        request.registry = self.registry
        request.invoke_subrequest = self.invoke_subrequest
        extensions = self.request_extensions
        if extensions is not None:
            apply_request_extensions(request, extensions=extensions)
        return RequestContext(request)

    def invoke_request(self, request, _use_tweens=True):
        """
        Execute a request through the request processing pipeline and
        return the generated response.

        """
        registry = self.registry
        has_listeners = registry.has_listeners
        notify = registry.notify

        if _use_tweens:
            handle_request = self.handle_request
        else:
            handle_request = self.orig_handle_request

        try:
            response = handle_request(request)

            if request.response_callbacks:
                request._process_response_callbacks(response)

            has_listeners and notify(NewResponse(request, response))

            return response

        finally:
            if request.finished_callbacks:
                request._process_finished_callbacks()

    def __call__(self, environ, start_response):
        """
        Accept ``environ`` and ``start_response``; create a
        :term:`request` and route the request to a :app:`Pyramid`
        view based on introspection of :term:`view configuration`
        within the application registry; call ``start_response`` and
        return an iterable.
        """
        response = self.execution_policy(environ, self)
        return response(environ, start_response)


def default_execution_policy(environ, router):
    with router.request_context(environ) as request:
        return router.invoke_request(request)

```
--- 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:** Reference Cycle Caused by Unremoved `context` in Request Object

**Description:**
After processing a request, the `request` object retains a reference to the `context`. This prevents the garbage collector from reclaiming memory, leading to reference cycles and potential memory leaks in long-running applications.

**Example:**
```python
def handle_request():
    request = Request()
    context = Context()
    request.context = context

    def view(context, request):
        request.add_finished_callback(lambda req: None)
        return Response('OK')

    router = Router()
    router.process(request, view)

    # After processing, 'context' should be removed
    assert not hasattr(request, 'context')
```

**Expected Behavior:**
After the request is processed, the `context` attribute should be removed from the `request` object to break the reference cycle, allowing proper garbage collection.

**Actual Behavior:**
The `context` attribute remains on the `request` object, maintaining a reference cycle and preventing garbage collection.
[/ISSUE]
{
    "TestRouter.test_call_eventsends": "PASSED",
    "TestRouter.test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview": "PASSED",
    "TestRouter.test_call_no_view_registered_debug_notfound_false": "PASSED",
    "TestRouter.test_call_no_view_registered_debug_notfound_true": "PASSED",
    "TestRouter.test_call_no_view_registered_no_isettings": "PASSED",
    "TestRouter.test_call_request_factory_raises": "PASSED",
    "TestRouter.test_call_request_has_response_callbacks": "PASSED",
    "TestRouter.test_call_route_match_miss_debug_routematch": "PASSED",
    "TestRouter.test_call_route_matches_and_has_factory": "PASSED",
    "TestRouter.test_call_route_matches_doesnt_overwrite_subscriber_iface": "PASSED",
    "TestRouter.test_call_route_raises_exception_another_exception_view": "PASSED",
    "TestRouter.test_call_route_raises_exception_view": "PASSED",
    "TestRouter.test_call_route_raises_exception_view_another_route": "PASSED",
    "TestRouter.test_call_route_raises_exception_view_specializing": "PASSED",
    "TestRouter.test_call_route_raises_route_exception_view": "PASSED",
    "TestRouter.test_call_route_raises_sub_exception_super_exception_view": "PASSED",
    "TestRouter.test_call_route_raises_super_exception_sub_exception_view": "PASSED",
    "TestRouter.test_call_traverser_default": "PASSED",
    "TestRouter.test_call_view_exception_propagating": "PASSED",
    "TestRouter.test_call_view_multiple_predicate_mismatches_dont_hide_views": "PASSED",
    "TestRouter.test_call_view_predicate_mismatch_doesnt_find_unrelated_views": "PASSED",
    "TestRouter.test_call_view_predicate_mismatch_doesnt_hide_views": "PASSED",
    "TestRouter.test_call_view_raises_exception_another_exception_view": "PASSED",
    "TestRouter.test_call_view_raises_exception_route_view": "PASSED",
    "TestRouter.test_call_view_raises_exception_view": "PASSED",
    "TestRouter.test_call_view_raises_exception_view_route": "PASSED",
    "TestRouter.test_call_view_raises_forbidden": "PASSED",
    "TestRouter.test_call_view_raises_notfound": "PASSED",
    "TestRouter.test_call_view_raises_predicate_mismatch": "PASSED",
    "TestRouter.test_call_view_raises_response_cleared": "PASSED",
    "TestRouter.test_call_view_raises_sub_exception_super_exception_view": "PASSED",
    "TestRouter.test_call_view_raises_super_exception_sub_exception_view": "PASSED",
    "TestRouter.test_call_view_registered_nonspecific_default_path": "PASSED",
    "TestRouter.test_call_view_registered_nonspecific_nondefault_path_and_subpath": "PASSED",
    "TestRouter.test_call_view_registered_specific_fail": "PASSED",
    "TestRouter.test_call_view_registered_specific_success": "PASSED",
    "TestRouter.test_call_view_returns_adapted_response": "PASSED",
    "TestRouter.test_call_view_returns_non_iresponse": "PASSED",
    "TestRouter.test_call_with_request_extensions": "PASSED",
    "TestRouter.test_ctor_registry_has_no_settings": "PASSED",
    "TestRouter.test_custom_execution_policy": "PASSED",
    "TestRouter.test_exception_view_returns_non_iresponse": "PASSED",
    "TestRouter.test_execution_policy_bubbles_exception": "PASSED",
    "TestRouter.test_finish_request_when_view_raises": "PASSED",
    "TestRouter.test_finish_request_when_view_succeeds": "PASSED",
    "TestRouter.test_request_context_manually": "PASSED",
    "TestRouter.test_request_context_with_statement": "PASSED",
    "TestRouter.test_request_factory": "PASSED",
    "TestRouter.test_root_factory_exception_propagating": "PASSED",
    "TestRouter.test_root_factory_raises_exception_view": "PASSED",
    "TestRouter.test_root_factory_raises_forbidden": "PASSED",
    "TestRouter.test_root_factory_raises_notfound": "PASSED",
    "TestRouter.test_root_policy": "PASSED",
    "TestRouter.test_traverser_exception_propagating": "PASSED",
    "TestRouter.test_traverser_raises_exception_view": "PASSED",
    "TestRouter.test_traverser_raises_forbidden_class": "PASSED",
    "TestRouter.test_traverser_raises_forbidden_instance": "PASSED",
    "TestRouter.test_traverser_raises_notfound_class": "PASSED",
    "TestRouter.test_traverser_raises_notfound_instance": "PASSED",
    "TestRouter.test_tween_factories": "PASSED",
    "ActionConfiguratorMixinTests.test_action_autocommit_with_introspectables": "PASSED",
    "ActionConfiguratorMixinTests.test_action_autocommit_with_introspectables_introspection_off": "PASSED",
    "ActionConfiguratorMixinTests.test_action_branching_kw_is_None": "PASSED",
    "ActionConfiguratorMixinTests.test_action_branching_kw_is_not_None": "PASSED",
    "ActionConfiguratorMixinTests.test_action_branching_nonautocommit_with_config_info": "PASSED",
    "ActionConfiguratorMixinTests.test_action_branching_nonautocommit_with_introspectables": "PASSED",
    "ActionConfiguratorMixinTests.test_action_branching_nonautocommit_without_config_info": "PASSED",
    "ActionConfiguratorMixinTests.test_action_nonautocommit_with_introspectables_introspection_off": "PASSED",
    "ActionConfiguratorMixinTests.test_autocommit_no_conflicts": "PASSED",
    "ActionConfiguratorMixinTests.test_commit_conflict_resolved_with_include": "PASSED",
    "ActionConfiguratorMixinTests.test_commit_conflict_resolved_with_two_includes_and_local": "PASSED",
    "ActionConfiguratorMixinTests.test_commit_conflict_simple": "PASSED",
    "ActionConfiguratorMixinTests.test_commit_conflict_with_two_includes": "PASSED",
    "ActionConfiguratorMixinTests.test_conflict_set_forbidden_view": "PASSED",
    "ActionConfiguratorMixinTests.test_conflict_set_notfound_view": "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_executing_conflicting_action_across_orders": "PASSED",
    "TestActionState.test_executing_conflicting_action_across_reentrant_orders": "PASSED",
    "TestActionState.test_it": "PASSED",
    "TestActionState.test_processSpec": "PASSED",
    "TestActionState.test_reentrant_action": "PASSED",
    "TestActionState.test_reentrant_action_error": "PASSED",
    "TestActionState.test_reentrant_action_with_deferred_discriminator": "PASSED",
    "TestActionState.test_reentrant_action_without_clear": "PASSED",
    "Test_reentrant_action_functional.test_deferred_discriminator": "PASSED",
    "Test_reentrant_action_functional.test_functional": "PASSED",
    "Test_resolveConflicts.test_conflicts_across_orders": "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",
    "Test_resolveConflicts.test_override_success_across_orders": "PASSED",
    "TestActionInfo.test___str__": "PASSED",
    "TestActionInfo.test_class_conforms": "PASSED",
    "TestActionInfo.test_ctor": "PASSED",
    "TestActionInfo.test_instance_conforms": "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_absdirectory": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_directory_with_absfile": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_directory_with_file": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_file_with_absdirectory": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_file_with_absfile": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_file_with_directory": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_file_with_missing_abspath": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_file_with_package": "PASSED",
    "TestAssetsConfiguratorMixin.test_override_asset_package_with_absdirectory": "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_filtered_sources": "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": "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",
    "TestPackageAssetSource.test_exists": "PASSED",
    "TestPackageAssetSource.test_exists_file_doesnt_exist": "PASSED",
    "TestPackageAssetSource.test_exists_with_prefix": "PASSED",
    "TestPackageAssetSource.test_get_filename_file_doesnt_exist": "PASSED",
    "TestPackageAssetSource.test_get_stream": "PASSED",
    "TestPackageAssetSource.test_get_stream_file_doesnt_exist": "PASSED",
    "TestPackageAssetSource.test_get_stream_with_prefix": "PASSED",
    "TestPackageAssetSource.test_get_string": "PASSED",
    "TestPackageAssetSource.test_get_string_file_doesnt_exist": "PASSED",
    "TestPackageAssetSource.test_get_string_with_prefix": "PASSED",
    "TestPackageAssetSource.test_isdir_doesnt_exist": "PASSED",
    "TestPackageAssetSource.test_isdir_false": "PASSED",
    "TestPackageAssetSource.test_isdir_true": "PASSED",
    "TestPackageAssetSource.test_listdir": "PASSED",
    "TestPackageAssetSource.test_listdir_doesnt_exist": "PASSED",
    "TestFSAssetSource.test_exists": "PASSED",
    "TestFSAssetSource.test_exists_file_doesnt_exist": "PASSED",
    "TestFSAssetSource.test_exists_with_prefix": "PASSED",
    "TestFSAssetSource.test_get_filename": "PASSED",
    "TestFSAssetSource.test_get_filename_file_doesnt_exist": "PASSED",
    "TestFSAssetSource.test_get_filename_with_prefix": "PASSED",
    "TestFSAssetSource.test_get_stream": "PASSED",
    "TestFSAssetSource.test_get_stream_file_doesnt_exist": "PASSED",
    "TestFSAssetSource.test_get_stream_with_prefix": "PASSED",
    "TestFSAssetSource.test_get_string": "PASSED",
    "TestFSAssetSource.test_get_string_file_doesnt_exist": "PASSED",
    "TestFSAssetSource.test_get_string_with_prefix": "PASSED",
    "TestFSAssetSource.test_isdir_doesnt_exist": "PASSED",
    "TestFSAssetSource.test_isdir_false": "PASSED",
    "TestFSAssetSource.test_isdir_true": "PASSED",
    "TestFSAssetSource.test_listdir": "PASSED",
    "TestFSAssetSource.test_listdir_doesnt_exist": "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_text_name": "PASSED",
    "TestFactoriesMixin.test_add_request_method_with_unnamed_callable": "PASSED",
    "TestFactoriesMixin.test_set_execution_policy": "PASSED",
    "TestFactoriesMixin.test_set_execution_policy_to_None": "PASSED",
    "TestFactoriesMixin.test_set_multiple_request_methods_conflict": "PASSED",
    "TestFactoriesMixin.test_set_request_factory": "PASSED",
    "TestFactoriesMixin.test_set_response_factory": "PASSED",
    "TestFactoriesMixin.test_set_root_factory": "PASSED",
    "TestFactoriesMixin.test_set_root_factory_as_None": "PASSED",
    "TestFactoriesMixin.test_set_session_factory": "PASSED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_invalid_kwargs": "PASSED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_missing_dir": "PASSED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_no_specs": "PASSED",
    "TestI18NConfiguratorMixin.test_set_locale_negotiator": "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_adds__lock": "PASSED",
    "ConfiguratorTests.test__fix_registry_adds_clear_view_lookup_cache": "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_begin": "PASSED",
    "ConfiguratorTests.test_begin_does_not_propagate_request_for_diff_registry": "PASSED",
    "ConfiguratorTests.test_begin_overrides_request": "PASSED",
    "ConfiguratorTests.test_begin_propagates_request_for_same_registry": "PASSED",
    "ConfiguratorTests.test_begin_with_request": "PASSED",
    "ConfiguratorTests.test_context_manager": "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_security_policy": "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_threadlocals_active": "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_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_conflict": "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_response_factory": "PASSED",
    "ConfiguratorTests.test_unhook_zca": "PASSED",
    "ConfiguratorTests.test_with_package": "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",
    "TestGlobalRegistriesIntegration.test_global_registries": "PASSED",
    "TestGlobalRegistriesIntegration.test_global_registries_empty": "PASSED",
    "TestPredicateList.test_custom_predicates_can_affect_traversal": "PASSED",
    "TestPredicateList.test_different_custom_predicates_with_same_hash": "PASSED",
    "TestPredicateList.test_header_multiple": "PASSED",
    "TestPredicateList.test_header_multiple_fails": "PASSED",
    "TestPredicateList.test_header_multiple_mixed": "PASSED",
    "TestPredicateList.test_header_multiple_mixed_fails": "PASSED",
    "TestPredicateList.test_header_multiple_with_values": "PASSED",
    "TestPredicateList.test_header_multiple_with_values_fails": "PASSED",
    "TestPredicateList.test_header_simple": "PASSED",
    "TestPredicateList.test_header_simple_fails": "PASSED",
    "TestPredicateList.test_header_with_value": "PASSED",
    "TestPredicateList.test_header_with_value_fails": "PASSED",
    "TestPredicateList.test_header_with_value_fails_case": "PASSED",
    "TestPredicateList.test_is_authenticated_false_fails": "PASSED",
    "TestPredicateList.test_is_authenticated_false_matches": "PASSED",
    "TestPredicateList.test_is_authenticated_true_fails": "PASSED",
    "TestPredicateList.test_is_authenticated_true_matches": "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_close_matches": "PASSED",
    "TestPredicateList.test_predicate_text_is_correct": "PASSED",
    "TestPredicateList.test_predicate_text_is_correct_when_multiple": "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_sort_accept_offers.test_default_specificities": "PASSED",
    "Test_sort_accept_offers.test_params_inherit_type_prefs": "PASSED",
    "Test_sort_accept_offers.test_params_order": "PASSED",
    "Test_sort_accept_offers.test_specific_type_order": "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_effective_principals_deprecated": "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_accept_list": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_custom_predicates": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_factory": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_header": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_inherit_errors": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_is_authenticated": "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_root_slash_with_route_prefix": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_route_prefix": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_route_prefix_with_inherit_slash": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_static": "PASSED",
    "RoutesConfiguratorMixinTests.test_add_route_with_wildcard_accept_raises": "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_changing_set_default_csrf_options": "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_authentication_policy_with_security_policy": "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_csrf_options": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_default_permission": "PASSED",
    "ConfiguratorSecurityMethodsTests.test_set_security_policy": "PASSED",
    "TestSettingsConfiguratorMixin.test__set_settings_as_None": "PASSED",
    "TestSettingsConfiguratorMixin.test__set_settings_as_dictwithvalues": "PASSED",
    "TestSettingsConfiguratorMixin.test__set_settings_does_not_uses_original_dict": "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",
    "TestSettingsConfiguratorMixin.test_settings_parameter_dict_is_never_updated": "PASSED",
    "TestSettings.test_csrf_trusted_origins": "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_noargs": "PASSED",
    "TestSettings.test_originals_kept": "PASSED",
    "TestSettings.test_prevent_cachebust": "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_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_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_with_over_nonstringoriter": "PASSED",
    "TestTweensConfiguratorMixin.test_add_tweens_names_with_under_nonstringoriter": "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",
    "TestViewsConfigurationMixin.test_add_accept_view_order_override": "PASSED",
    "TestViewsConfigurationMixin.test_add_accept_view_order_throws_on_type_mismatch": "PASSED",
    "TestViewsConfigurationMixin.test_add_accept_view_order_throws_on_wildcard": "PASSED",
    "TestViewsConfigurationMixin.test_add_exception_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_exception_view_disallows_exception_only": "PASSED",
    "TestViewsConfigurationMixin.test_add_exception_view_disallows_for_": "PASSED",
    "TestViewsConfigurationMixin.test_add_exception_view_disallows_name": "PASSED",
    "TestViewsConfigurationMixin.test_add_exception_view_disallows_permission": "PASSED",
    "TestViewsConfigurationMixin.test_add_exception_view_disallows_require_csrf": "PASSED",
    "TestViewsConfigurationMixin.test_add_exception_view_with_subclass": "PASSED",
    "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_name": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_disallows_permission": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_disallows_require_csrf": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_no_view_argument": "PASSED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_with_renderer": "PASSED",
    "TestViewsConfigurationMixin.test_add_normal_and_exception_view_intr_derived_callable": "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_append_slash_custom_response": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_disallows_context": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_disallows_for_": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_disallows_name": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_disallows_permission": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_disallows_require_csrf": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_no_view_argument": "PASSED",
    "TestViewsConfigurationMixin.test_add_notfound_view_with_renderer": "PASSED",
    "TestViewsConfigurationMixin.test_add_static_view_absolute": "PASSED",
    "TestViewsConfigurationMixin.test_add_static_view_here_no_utility_registered": "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_class_method_no_attr": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_context_as_class": "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_custom_predicate_bests_standard_predicate": "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_does_not_accept_iterable_accept": "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_multiviews": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exc_multiview_replaces_only_exc_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_only": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exception_only_misconfiguration": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exception_only_no_regular_view": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_exception_register_secured_view": "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_false": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_containment_true": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_csrf_header": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_csrf_param": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_custom_predicates_match": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_custom_predicates_nomatch": "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_is_authenticated_false_matches": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_is_authenticated_false_no_match": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_is_authenticated_true_matches": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_is_authenticated_true_no_match": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_mapper": "PASSED",
    "TestViewsConfigurationMixin.test_add_view_with_missing_csrf_header": "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_wildcard_accept_raises": "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_default_accept_view_order": "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_effective_principals_deprecated": "PASSED",
    "TestViewsConfigurationMixin.test_set_view_mapper": "PASSED",
    "TestViewsConfigurationMixin.test_set_view_mapper_dottedname": "PASSED",
    "TestViewsConfigurationMixin.test_view_with_most_specific_predicate": "PASSED",
    "TestViewsConfigurationMixin.test_view_with_most_specific_predicate_with_mismatch": "PASSED",
    "Test_runtime_exc_view.test_call": "PASSED",
    "Test_runtime_exc_view.test_call_dispatches_on_exception": "PASSED",
    "Test_runtime_exc_view.test_permitted": "PASSED",
    "Test_runtime_exc_view.test_permitted_dispatches_on_exception": "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",
    "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_cachebust_prevented": "PASSED",
    "TestStaticURLInfo.test_add_cachebuster": "PASSED",
    "TestStaticURLInfo.test_add_cachebuster_abspath": "PASSED",
    "TestStaticURLInfo.test_add_cachebuster_for_more_specific_path": "PASSED",
    "TestStaticURLInfo.test_add_cachebuster_overwrite": "PASSED",
    "TestStaticURLInfo.test_add_cachebuster_overwrite_explicit": "PASSED",
    "TestStaticURLInfo.test_add_package_root": "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_route_url": "PASSED",
    "TestStaticURLInfo.test_generate_slash_in_name1": "PASSED",
    "TestStaticURLInfo.test_generate_slash_in_name2": "PASSED",
    "TestStaticURLInfo.test_generate_url_cachebust": "PASSED",
    "TestStaticURLInfo.test_generate_url_cachebust_abspath": "PASSED",
    "TestStaticURLInfo.test_generate_url_cachebust_nomatch": "PASSED",
    "TestStaticURLInfo.test_generate_url_quoted_remote": "PASSED",
    "TestStaticURLInfo.test_generate_url_unquoted_local": "PASSED",
    "TestStaticURLInfo.test_generate_url_with_custom_anchor": "PASSED",
    "TestStaticURLInfo.test_generate_url_with_custom_query": "PASSED",
    "TestStaticURLInfo.test_verifyClass": "PASSED",
    "TestStaticURLInfo.test_verifyObject": "PASSED",
    "Test_view_description.test_with_text": "PASSED",
    "Test_viewdefaults.test_dunder_attrs_copied": "PASSED",
    "TestParseVars.test_parse_vars_bad": "PASSED",
    "TestParseVars.test_parse_vars_good": "PASSED",
    "TestPDistReportCommand.test_no_dists": "PASSED",
    "TestPDistReportCommand.test_with_dists": "PASSED",
    "TestPRequestCommand.test_command_display_headers": "PASSED",
    "TestPRequestCommand.test_command_has_bad_config_header": "PASSED",
    "TestPRequestCommand.test_command_has_content_type_header_var": "PASSED",
    "TestPRequestCommand.test_command_has_good_header_var": "PASSED",
    "TestPRequestCommand.test_command_has_multiple_header_vars": "PASSED",
    "TestPRequestCommand.test_command_method_configures_logging": "PASSED",
    "TestPRequestCommand.test_command_method_get": "PASSED",
    "TestPRequestCommand.test_command_method_options": "PASSED",
    "TestPRequestCommand.test_command_method_patch": "PASSED",
    "TestPRequestCommand.test_command_method_post": "PASSED",
    "TestPRequestCommand.test_command_method_propfind": "PASSED",
    "TestPRequestCommand.test_command_method_put": "PASSED",
    "TestPRequestCommand.test_command_not_enough_args": "PASSED",
    "TestPRequestCommand.test_command_path_doesnt_start_with_slash": "PASSED",
    "TestPRequestCommand.test_command_response_has_no_charset": "PASSED",
    "TestPRequestCommand.test_command_two_args": "PASSED",
    "TestPRequestCommand.test_command_w_basic_auth": "PASSED",
    "TestPRequestCommand.test_command_with_query_string": "PASSED",
    "Test_main.test_it": "PASSED",
    "TestPRoutesCommand.test__get_mapper": "PASSED",
    "TestPRoutesCommand.test_bad_args": "PASSED",
    "TestPRoutesCommand.test_bad_format": "PASSED",
    "TestPRoutesCommand.test_config_format_ini_commas": "PASSED",
    "TestPRoutesCommand.test_config_format_ini_newlines": "PASSED",
    "TestPRoutesCommand.test_config_format_ini_spaces": "PASSED",
    "TestPRoutesCommand.test_good_args": "PASSED",
    "TestPRoutesCommand.test_good_format": "PASSED",
    "TestPRoutesCommand.test_no_mapper": "PASSED",
    "TestPRoutesCommand.test_no_routes": "PASSED",
    "TestPRoutesCommand.test_route_as_wsgiapp": "PASSED",
    "TestPRoutesCommand.test_route_no_view": "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_with_factory": "PASSED",
    "TestPRoutesCommand.test_static_routes_included_in_list": "PASSED",
    "TestPServeCommand.test_config_file_finds_open_url": "PASSED",
    "TestPServeCommand.test_guess_server_url": "PASSED",
    "TestPServeCommand.test_original_ignore_files": "PASSED",
    "TestPServeCommand.test_parse_vars_bad": "PASSED",
    "TestPServeCommand.test_parse_vars_good": "PASSED",
    "TestPServeCommand.test_reload_call_hupper_with_correct_args": "PASSED",
    "TestPServeCommand.test_run_no_args": "PASSED",
    "TestPShellCommand.test_command_custom_section_override": "PASSED",
    "TestPShellCommand.test_command_default_shell_option": "PASSED",
    "TestPShellCommand.test_command_errors_with_unknown_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_ipython": "PASSED",
    "TestPShellCommand.test_command_loads_pythonstartup": "PASSED",
    "TestPShellCommand.test_command_loads_setup_from_options": "PASSED",
    "TestPShellCommand.test_command_setup": "PASSED",
    "TestPShellCommand.test_command_setup_generator": "PASSED",
    "TestPShellCommand.test_list_shells": "PASSED",
    "TestPShellCommand.test_shell_entry_points": "PASSED",
    "TestPShellCommand.test_shell_ordering": "PASSED",
    "TestPShellCommand.test_shell_override": "PASSED",
    "Test_python_shell_runner.test_it": "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_not_found": "PASSED",
    "TestPViewsCommand.test_views_command_not_found_url_starts_without_slash": "PASSED",
    "AdaptersConfiguratorMixinTests.test_add_resource_url_adapter_dotted_names": "FAILED",
    "AdaptersConfiguratorMixinTests.test_add_resource_url_adapter_introspectables": "FAILED",
    "AdaptersConfiguratorMixinTests.test_add_traverser_dotted_names": "FAILED",
    "TestAssetsConfiguratorMixin.test_override_asset_directory_with_directory": "FAILED",
    "TestAssetsConfiguratorMixin.test_override_asset_directory_with_package": "FAILED",
    "TestAssetsConfiguratorMixin.test_override_asset_file_with_file": "FAILED",
    "TestAssetsConfiguratorMixin.test_override_asset_package_with_directory": "FAILED",
    "TestAssetsConfiguratorMixin.test_override_asset_package_with_package": "FAILED",
    "TestOverrideProvider.test_get_resource_filename_no_overrides": "FAILED",
    "TestOverrideProvider.test_get_resource_filename_override_returns_None": "FAILED",
    "TestPackageAssetSource.test_get_filename": "FAILED",
    "TestPackageAssetSource.test_get_filename_with_prefix": "FAILED",
    "TestFactoriesMixin.test_set_request_factory_dottedname": "FAILED",
    "TestFactoriesMixin.test_set_response_factory_dottedname": "FAILED",
    "TestFactoriesMixin.test_set_root_factory_dottedname": "FAILED",
    "TestFactoriesMixin.test_set_session_factory_dottedname": "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_doesnt_use_override_w_autocommit": "FAILED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_multiple_specs": "FAILED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_multiple_specs_multiple_calls": "FAILED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_override_multiple_specs_multiple_calls": "FAILED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_uses_override_out_of_order": "FAILED",
    "TestI18NConfiguratorMixin.test_add_translation_dirs_uses_override_w_autocommit": "FAILED",
    "TestI18NConfiguratorMixin.test_set_locale_negotiator_dottedname": "FAILED",
    "ConfiguratorTests.test_ctor_no_registry": "FAILED",
    "ConfiguratorTests.test_ctor_noreg_debug_logger_None_default": "FAILED",
    "ConfiguratorTests.test_include_constant_root_package": "FAILED",
    "ConfiguratorTests.test_include_with_python_callable": "FAILED",
    "ConfiguratorTests.test_setup_registry_debug_logger_None_default": "FAILED",
    "ConfiguratorTests.test_setup_registry_tweens": "FAILED",
    "ConfiguratorTests.test_with_package_module": "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",
    "RoutesConfiguratorMixinTests.test_add_route_with_factory_dottedname": "FAILED",
    "TestingConfiguratorMixinTests.test_testing_add_subscriber_dottedname": "FAILED",
    "TestTweensConfiguratorMixin.test_add_tween_dottedname": "FAILED",
    "TestTweensConfiguratorMixin.test_add_tweens_names_distinct": "FAILED",
    "TestTweensConfiguratorMixin.test_add_tweens_names_with_underover": "FAILED",
    "TestViewsConfigurationMixin.test_add_exception_view_with_view_defaults": "FAILED",
    "TestViewsConfigurationMixin.test_add_forbidden_view_with_view_defaults": "FAILED",
    "TestViewsConfigurationMixin.test_add_notfound_view_with_view_defaults": "FAILED",
    "TestViewsConfigurationMixin.test_add_static_view_package_here_relative": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_context_as_dottedname": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_for__as_dottedname": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_with_containment_dottedname": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_with_template_renderer": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_with_template_renderer_no_callable": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_with_view_defaults": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_with_view_defaults_viewname_is_dottedname_kwarg": "FAILED",
    "TestViewsConfigurationMixin.test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg": "FAILED",
    "TestStaticURLInfo.test_generate_url_cachebust_with_overrides": "FAILED",
    "Test_view_description.test_without_text": "FAILED",
    "TestPRoutesCommand.test_class_view": "FAILED",
    "TestPRoutesCommand.test_one_route_all_methods_view_only_post": "FAILED",
    "TestPRoutesCommand.test_one_route_only_post_view_all_methods": "FAILED",
    "TestPRoutesCommand.test_one_route_only_post_view_post_and_get": "FAILED",
    "TestPRoutesCommand.test_one_route_with_long_name_one_view_registered": "FAILED",
    "TestPRoutesCommand.test_route_is_get_view_request_method_not_post": "FAILED",
    "TestPRoutesCommand.test_route_request_method_mismatch": "FAILED",
    "TestPRoutesCommand.test_route_static_views": "FAILED",
    "TestPRoutesCommand.test_single_route_multiview_registered": "FAILED",
    "TestPRoutesCommand.test_single_route_one_view_registered": "FAILED",
    "TestPRoutesCommand.test_view_glob": "FAILED",
    "TestPRoutesCommand.test_view_request_method_not_post": "FAILED",
    "TestPServeCommand.test_config_file_finds_watch_files": "FAILED",
    "TestPViewsCommand.test_views_command_multi_view_nested": "FAILED",
    "TestPViewsCommand.test_views_command_multiview": "FAILED",
    "TestPViewsCommand.test_views_command_multiview_with_permission": "FAILED",
    "TestPViewsCommand.test_views_command_multiview_with_predicates": "FAILED",
    "TestPViewsCommand.test_views_command_single_view_function_traversal": "FAILED",
    "TestPViewsCommand.test_views_command_single_view_route": "FAILED",
    "TestPViewsCommand.test_views_command_single_view_route_with_route_predicates": "FAILED",
    "TestPViewsCommand.test_views_command_single_view_traversal": "FAILED",
    "TestPViewsCommand.test_views_command_single_view_traversal_with_permission": "FAILED",
    "TestPViewsCommand.test_views_command_single_view_traversal_with_predicates": "FAILED"
}
diff --git a/src/pyramid/router.py b/src/pyramid/router.py
index 644a6a395..61660c41b 100644
--- a/src/pyramid/router.py
+++ b/src/pyramid/router.py
@@ -252,8 +252,12 @@ class Router:
             return response
 
         finally:
-            if request.finished_callbacks:
-                request._process_finished_callbacks()
+            self.finish_request(request)
+
+    def finish_request(self, request):
+        if request.finished_callbacks:
+            request._process_finished_callbacks()
+        request.__dict__.pop('context', None)  # Break potential ref cycle
 
     def __call__(self, environ, start_response):
         """

{"src/pyramid/router.py": "from zope.interface import implementer, providedBy\n\nfrom pyramid.events import (\n    BeforeTraversal,\n    ContextFound,\n    NewRequest,\n    NewResponse,\n)\nfrom pyramid.httpexceptions import HTTPNotFound\nfrom pyramid.interfaces import (\n    IDebugLogger,\n    IExecutionPolicy,\n    IRequest,\n    IRequestExtensions,\n    IRequestFactory,\n    IRootFactory,\n    IRouter,\n    IRouteRequest,\n    IRoutesMapper,\n    ITraverser,\n    ITweens,\n)\nfrom pyramid.request import Request, apply_request_extensions\nfrom pyramid.threadlocal import RequestContext\nfrom pyramid.traversal import DefaultRootFactory, ResourceTreeTraverser\nfrom pyramid.view import _call_view\n\n\n@implementer(IRouter)\nclass Router:\n\n    debug_notfound = False\n    debug_routematch = False\n\n    def __init__(self, registry):\n        q = registry.queryUtility\n        self.logger = q(IDebugLogger)\n        self.root_factory = q(IRootFactory, default=DefaultRootFactory)\n        self.routes_mapper = q(IRoutesMapper)\n        self.request_factory = q(IRequestFactory, default=Request)\n        self.request_extensions = q(IRequestExtensions)\n        self.execution_policy = q(\n            IExecutionPolicy, default=default_execution_policy\n        )\n        self.orig_handle_request = self.handle_request\n        tweens = q(ITweens)\n        if tweens is not None:\n            self.handle_request = tweens(self.handle_request, registry)\n        self.root_policy = self.root_factory  # b/w compat\n        self.registry = registry\n        settings = registry.settings\n        if settings is not None:\n            self.debug_notfound = settings['debug_notfound']\n            self.debug_routematch = settings['debug_routematch']\n\n    def handle_request(self, request):\n        attrs = request.__dict__\n        registry = attrs['registry']\n\n        request.request_iface = IRequest\n        context = None\n        routes_mapper = self.routes_mapper\n        debug_routematch = self.debug_routematch\n        adapters = registry.adapters\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n        logger = self.logger\n\n        has_listeners and notify(NewRequest(request))\n        # find the root object\n        root_factory = self.root_factory\n        if routes_mapper is not None:\n            info = routes_mapper(request)\n            match, route = info['match'], info['route']\n            if route is None:\n                if debug_routematch:\n                    msg = 'no route matched for url %s' % request.url\n                    logger and logger.debug(msg)\n            else:\n                attrs['matchdict'] = match\n                attrs['matched_route'] = route\n\n                if debug_routematch:\n                    msg = (\n                        'route matched for url %s; '\n                        'route_name: %r, '\n                        'path_info: %r, '\n                        'pattern: %r, '\n                        'matchdict: %r, '\n                        'predicates: %r'\n                        % (\n                            request.url,\n                            route.name,\n                            request.path_info,\n                            route.pattern,\n                            match,\n                            ', '.join([p.text() for p in route.predicates]),\n                        )\n                    )\n                    logger and logger.debug(msg)\n\n                request.request_iface = registry.queryUtility(\n                    IRouteRequest, name=route.name, default=IRequest\n                )\n\n                root_factory = route.factory or self.root_factory\n\n        # Notify anyone listening that we are about to start traversal\n        #\n        # Notify before creating root_factory in case we want to do something\n        # special on a route we may have matched. See\n        # https://github.com/Pylons/pyramid/pull/1876 for ideas of what is\n        # possible.\n        has_listeners and notify(BeforeTraversal(request))\n\n        # Create the root factory\n        root = root_factory(request)\n        attrs['root'] = root\n\n        # We are about to traverse and find a context\n        traverser = adapters.queryAdapter(root, ITraverser)\n        if traverser is None:\n            traverser = ResourceTreeTraverser(root)\n        tdict = traverser(request)\n\n        context, view_name, subpath, traversed, vroot, vroot_path = (\n            tdict['context'],\n            tdict['view_name'],\n            tdict['subpath'],\n            tdict['traversed'],\n            tdict['virtual_root'],\n            tdict['virtual_root_path'],\n        )\n\n        attrs.update(tdict)\n\n        # Notify anyone listening that we have a context and traversal is\n        # complete\n        has_listeners and notify(ContextFound(request))\n\n        # find a view callable\n        context_iface = providedBy(context)\n        response = _call_view(\n            registry, request, context, context_iface, view_name\n        )\n\n        if response is None:\n            if self.debug_notfound:\n                msg = (\n                    'debug_notfound of url %s; path_info: %r, '\n                    'context: %r, view_name: %r, subpath: %r, '\n                    'traversed: %r, root: %r, vroot: %r, '\n                    'vroot_path: %r'\n                    % (\n                        request.url,\n                        request.path_info,\n                        context,\n                        view_name,\n                        subpath,\n                        traversed,\n                        root,\n                        vroot,\n                        vroot_path,\n                    )\n                )\n                logger and logger.debug(msg)\n            else:\n                msg = request.path_info\n            raise HTTPNotFound(msg)\n\n        return response\n\n    def invoke_subrequest(self, request, use_tweens=False):\n        \"\"\"Obtain a response object from the Pyramid application based on\n        information in the ``request`` object provided.  The ``request``\n        object must be an object that implements the Pyramid request\n        interface (such as a :class:`pyramid.request.Request` instance).  If\n        ``use_tweens`` is ``True``, the request will be sent to the\n        :term:`tween` in the tween stack closest to the request ingress.  If\n        ``use_tweens`` is ``False``, the request will be sent to the main\n        router handler, and no tweens will be invoked.\n\n        See the API for pyramid.request for complete documentation.\n        \"\"\"\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        with RequestContext(request):\n            return self.invoke_request(request, _use_tweens=use_tweens)\n\n    def request_context(self, environ):\n        \"\"\"\n        Create a new request context from a WSGI environ.\n\n        The request context is used to push/pop the threadlocals required\n        when processing the request. It also contains an initialized\n        :class:`pyramid.interfaces.IRequest` instance using the registered\n        :class:`pyramid.interfaces.IRequestFactory`. The context may be\n        used as a context manager to control the threadlocal lifecycle:\n\n        .. code-block:: python\n\n            with router.request_context(environ) as request:\n                ...\n\n        Alternatively, the context may be used without the ``with`` statement\n        by manually invoking its ``begin()`` and ``end()`` methods.\n\n        .. code-block:: python\n\n            ctx = router.request_context(environ)\n            request = ctx.begin()\n            try:\n                ...\n            finally:\n                ctx.end()\n\n        \"\"\"\n        request = self.request_factory(environ)\n        request.registry = self.registry\n        request.invoke_subrequest = self.invoke_subrequest\n        extensions = self.request_extensions\n        if extensions is not None:\n            apply_request_extensions(request, extensions=extensions)\n        return RequestContext(request)\n\n    def invoke_request(self, request, _use_tweens=True):\n        \"\"\"\n        Execute a request through the request processing pipeline and\n        return the generated response.\n\n        \"\"\"\n        registry = self.registry\n        has_listeners = registry.has_listeners\n        notify = registry.notify\n\n        if _use_tweens:\n            handle_request = self.handle_request\n        else:\n            handle_request = self.orig_handle_request\n\n        try:\n            response = handle_request(request)\n\n            if request.response_callbacks:\n                request._process_response_callbacks(response)\n\n            has_listeners and notify(NewResponse(request, response))\n\n            return response\n\n        finally:\n            if request.finished_callbacks:\n                request._process_finished_callbacks()\n\n    def __call__(self, environ, start_response):\n        \"\"\"\n        Accept ``environ`` and ``start_response``; create a\n        :term:`request` and route the request to a :app:`Pyramid`\n        view based on introspection of :term:`view configuration`\n        within the application registry; call ``start_response`` and\n        return an iterable.\n        \"\"\"\n        response = self.execution_policy(environ, self)\n        return response(environ, start_response)\n\n\ndef default_execution_policy(environ, router):\n    with router.request_context(environ) as request:\n        return router.invoke_request(request)\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:** Reference Cycle Caused by Unremoved `context` in Request Object

**Description:**
After processing a request, the `request` object retains a reference to the `context`. This prevents the garbage collector from reclaiming memory, leading to reference cycles and potential memory leaks in long-running applications.

**Example:**
```python
def handle_request():
    request = Request()
    context = Context()
    request.context = context

    def view(context, request):
        request.add_finished_callback(lambda req: None)
        return Response('OK')

    router = Router()
    router.process(request, view)

    # After processing, 'context' should be removed
    assert not hasattr(request, 'context')
```

**Expected Behavior:**
After the request is processed, the `context` attribute should be removed from the `request` object to break the reference cycle, allowing proper garbage collection.

**Actual Behavior:**
The `context` attribute remains on the `request` object, maintaining a reference cycle and preventing garbage collection.
[/ISSUE]
--- END ISSUE ---

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

--- BEGIN FILE ---
```
### src/pyramid/router.py
from zope.interface import implementer, providedBy

from pyramid.events import (
    BeforeTraversal,
    ContextFound,
    NewRequest,
    NewResponse,
)
from pyramid.httpexceptions import HTTPNotFound
from pyramid.interfaces import (
    IDebugLogger,
    IExecutionPolicy,
    IRequest,
    IRequestExtensions,
    IRequestFactory,
    IRootFactory,
    IRouter,
    IRouteRequest,
    IRoutesMapper,
    ITraverser,
    ITweens,
)
from pyramid.request import Request, apply_request_extensions
from pyramid.threadlocal import RequestContext
from pyramid.traversal import DefaultRootFactory, ResourceTreeTraverser
from pyramid.view import _call_view


@implementer(IRouter)
class Router:

    debug_notfound = False
    debug_routematch = False

    def __init__(self, registry):
        q = registry.queryUtility
        self.logger = q(IDebugLogger)
        self.root_factory = q(IRootFactory, default=DefaultRootFactory)
        self.routes_mapper = q(IRoutesMapper)
        self.request_factory = q(IRequestFactory, default=Request)
        self.request_extensions = q(IRequestExtensions)
        self.execution_policy = q(
            IExecutionPolicy, default=default_execution_policy
        )
        self.orig_handle_request = self.handle_request
        tweens = q(ITweens)
        if tweens is not None:
            self.handle_request = tweens(self.handle_request, registry)
        self.root_policy = self.root_factory  # b/w compat
        self.registry = registry
        settings = registry.settings
        if settings is not None:
            self.debug_notfound = settings['debug_notfound']
            self.debug_routematch = settings['debug_routematch']

    def handle_request(self, request):
        attrs = request.__dict__
        registry = attrs['registry']

        request.request_iface = IRequest
        context = None
        routes_mapper = self.routes_mapper
        debug_routematch = self.debug_routematch
        adapters = registry.adapters
        has_listeners = registry.has_listeners
        notify = registry.notify
        logger = self.logger

        has_listeners and notify(NewRequest(request))
        # find the root object
        root_factory = self.root_factory
        if routes_mapper is not None:
            info = routes_mapper(request)
            match, route = info['match'], info['route']
            if route is None:
                if debug_routematch:
                    msg = 'no route matched for url %s' % request.url
                    logger and logger.debug(msg)
            else:
                attrs['matchdict'] = match
                attrs['matched_route'] = route

                if debug_routematch:
                    msg = (
                        'route matched for url %s; '
                        'route_name: %r, '
                        'path_info: %r, '
                        'pattern: %r, '
                        'matchdict: %r, '
                        'predicates: %r'
                        % (
                            request.url,
                            route.name,
                            request.path_info,
                            route.pattern,
                            match,
                            ', '.join([p.text() for p in route.predicates]),
                        )
                    )
                    logger and logger.debug(msg)

                request.request_iface = registry.queryUtility(
                    IRouteRequest, name=route.name, default=IRequest
                )

                root_factory = route.factory or self.root_factory

        # Notify anyone listening that we are about to start traversal
        #
        # Notify before creating root_factory in case we want to do something
        # special on a route we may have matched. See
        # https://github.com/Pylons/pyramid/pull/1876 for ideas of what is
        # possible.
        has_listeners and notify(BeforeTraversal(request))

        # Create the root factory
        root = root_factory(request)
        attrs['root'] = root

        # We are about to traverse and find a context
        traverser = adapters.queryAdapter(root, ITraverser)
        if traverser is None:
            traverser = ResourceTreeTraverser(root)
        tdict = traverser(request)

        context, view_name, subpath, traversed, vroot, vroot_path = (
            tdict['context'],
            tdict['view_name'],
            tdict['subpath'],
            tdict['traversed'],
            tdict['virtual_root'],
            tdict['virtual_root_path'],
        )

        attrs.update(tdict)

        # Notify anyone listening that we have a context and traversal is
        # complete
        has_listeners and notify(ContextFound(request))

        # find a view callable
        context_iface = providedBy(context)
        response = _call_view(
            registry, request, context, context_iface, view_name
        )

        if response is None:
            if self.debug_notfound:
                msg = (
                    'debug_notfound of url %s; path_info: %r, '
                    'context: %r, view_name: %r, subpath: %r, '
                    'traversed: %r, root: %r, vroot: %r, '
                    'vroot_path: %r'
                    % (
                        request.url,
                        request.path_info,
                        context,
                        view_name,
                        subpath,
                        traversed,
                        root,
                        vroot,
                        vroot_path,
                    )
                )
                logger and logger.debug(msg)
            else:
                msg = request.path_info
            raise HTTPNotFound(msg)

        return response

    def invoke_subrequest(self, request, use_tweens=False):
        """Obtain a response object from the Pyramid application based on
        information in the ``request`` object provided.  The ``request``
        object must be an object that implements the Pyramid request
        interface (such as a :class:`pyramid.request.Request` instance).  If
        ``use_tweens`` is ``True``, the request will be sent to the
        :term:`tween` in the tween stack closest to the request ingress.  If
        ``use_tweens`` is ``False``, the request will be sent to the main
        router handler, and no tweens will be invoked.

        See the API for pyramid.request for complete documentation.
        """
        request.registry = self.registry
        request.invoke_subrequest = self.invoke_subrequest
        extensions = self.request_extensions
        if extensions is not None:
            apply_request_extensions(request, extensions=extensions)
        with RequestContext(request):
            return self.invoke_request(request, _use_tweens=use_tweens)

    def request_context(self, environ):
        """
        Create a new request context from a WSGI environ.

        The request context is used to push/pop the threadlocals required
        when processing the request. It also contains an initialized
        :class:`pyramid.interfaces.IRequest` instance using the registered
        :class:`pyramid.interfaces.IRequestFactory`. The context may be
        used as a context manager to control the threadlocal lifecycle:

        .. code-block:: python

            with router.request_context(environ) as request:
                ...

        Alternatively, the context may be used without the ``with`` statement
        by manually invoking its ``begin()`` and ``end()`` methods.

        .. code-block:: python

            ctx = router.request_context(environ)
            request = ctx.begin()
            try:
                ...
            finally:
                ctx.end()

        """
        request = self.request_factory(environ)
        request.registry = self.registry
        request.invoke_subrequest = self.invoke_subrequest
        extensions = self.request_extensions
        if extensions is not None:
            apply_request_extensions(request, extensions=extensions)
        return RequestContext(request)

    def invoke_request(self, request, _use_tweens=True):
        """
        Execute a request through the request processing pipeline and
        return the generated response.

        """
        registry = self.registry
        has_listeners = registry.has_listeners
        notify = registry.notify

        if _use_tweens:
            handle_request = self.handle_request
        else:
            handle_request = self.orig_handle_request

        try:
            response = handle_request(request)

            if request.response_callbacks:
                request._process_response_callbacks(response)

            has_listeners and notify(NewResponse(request, response))

            return response

        finally:
            if request.finished_callbacks:
                request._process_finished_callbacks()

    def __call__(self, environ, start_response):
        """
        Accept ``environ`` and ``start_response``; create a
        :term:`request` and route the request to a :app:`Pyramid`
        view based on introspection of :term:`view configuration`
        within the application registry; call ``start_response`` and
        return an iterable.
        """
        response = self.execution_policy(environ, self)
        return response(environ, start_response)


def default_execution_policy(environ, router):
    with router.request_context(environ) as request:
        return router.invoke_request(request)

```
--- 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