diff --git a/aiohttp/web.py b/aiohttp/web.py index bba0f1b777..c67ece790b 100644 --- a/aiohttp/web.py +++ b/aiohttp/web.py @@ -6,6 +6,7 @@ from . import hdrs, web_exceptions, web_reqrep, web_urldispatcher, web_ws from .abc import AbstractMatchInfo, AbstractRouter +from .helpers import _sentinel from .log import web_logger from .protocol import HttpVersion # noqa from .server import ServerHttpProtocol @@ -221,8 +222,23 @@ def middlewares(self): return self._middlewares def make_handler(self, **kwargs): - return self._handler_factory( - self, self.router, loop=self.loop, **kwargs) + debug = kwargs.pop('debug', _sentinel) + if debug is not _sentinel: + warnings.warn( + "`debug` parameter is deprecated. " + "Use Application's debug mode instead", DeprecationWarning) + if debug != self.debug: + raise ValueError( + "The value of `debug` parameter conflicts with the debug " + "settings of the `Application` instance. The " + "application's debug mode setting should be used instead " + "as a single point to setup a debug mode. For more " + "information please check " + "http://aiohttp.readthedocs.io/en/stable/" + "web_reference.html#aiohttp.web.Application" + ) + return self._handler_factory(self, self.router, debug=self.debug, + loop=self.loop, **kwargs) @asyncio.coroutine def startup(self): diff --git a/docs/web_reference.rst b/docs/web_reference.rst index de90476d04..c35343b70f 100644 --- a/docs/web_reference.rst +++ b/docs/web_reference.rst @@ -1026,16 +1026,16 @@ Although :class:`Application` is a :obj:`dict`-like object, it can't be duplicated like one using :meth:`Application.copy`. .. class:: Application(*, loop=None, router=None, logger=, \ - middlewares=(), **kwargs) + middlewares=(), debug=False, **kwargs) The class inherits :class:`dict`. :param loop: :ref:`event loop` used - for processing HTTP requests. + for processing HTTP requests. - If param is ``None`` :func:`asyncio.get_event_loop` - used for getting default event loop, but we strongly - recommend to use explicit loops everywhere. + If param is ``None`` :func:`asyncio.get_event_loop` + used for getting default event loop, but we strongly + recommend to use explicit loops everywhere. :param router: :class:`aiohttp.abc.AbstractRouter` instance, the system creates :class:`UrlDispatcher` by default if @@ -1048,6 +1048,8 @@ duplicated like one using :meth:`Application.copy`. :param middlewares: :class:`list` of middleware factories, see :ref:`aiohttp-web-middlewares` for details. + :param debug: Switches debug mode. + .. attribute:: router Read-only property that returns *router instance*. @@ -1060,6 +1062,11 @@ duplicated like one using :meth:`Application.copy`. :ref:`event loop` used for processing HTTP requests. + + .. attribute:: debug + + Boolean value indicating whether the debug mode is turned on or off. + .. attribute:: on_response_prepare A :class:`~aiohttp.signals.Signal` that is fired at the beginning @@ -1129,6 +1136,13 @@ duplicated like one using :meth:`Application.copy`. :class:`~aiohttp.web.RequestHandlerFactory` constructor. + .. deprecated:: 1.0 + You should not pass ``debug`` parameter within ``kwargs`` since + its usage in :meth:`Application.make_handler` is deprecated in favor + of :attr:`Application.debug`. + The :class:`Application`'s debug mode setting should be used + as a single point to setup a debug mode. + You should pass result of the method as *protocol_factory* to :meth:`~asyncio.AbstractEventLoop.create_server`, e.g.:: diff --git a/tests/test_web_application.py b/tests/test_web_application.py index 718fc7f1ea..8b3a17203e 100644 --- a/tests/test_web_application.py +++ b/tests/test_web_application.py @@ -29,6 +29,26 @@ def test_app_default_loop(loop): assert loop is app.loop +@pytest.mark.parametrize('debug', [True, False]) +def test_app_make_handler_debug_exc(loop, mocker, debug): + app = web.Application(loop=loop, debug=debug) + + mocker.spy(app, '_handler_factory') + + app.make_handler() + with pytest.warns(DeprecationWarning) as exc: + app.make_handler(debug=debug) + + assert 'parameter is deprecated' in exc[0].message.args[0] + assert app._handler_factory.call_count == 2 + app._handler_factory.assert_called_with(app, app.router, loop=loop, + debug=debug) + + with pytest.raises(ValueError) as exc: + app.make_handler(debug=not debug) + assert 'The value of `debug` parameter conflicts with the' in str(exc) + + @asyncio.coroutine def test_app_register_on_finish(loop): app = web.Application(loop=loop)