Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop deprecated app.make_handler() #3939

Merged
merged 3 commits into from
Jul 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/3939.removal
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Drop deprecated ``Application.make_handler()``
57 changes: 0 additions & 57 deletions aiohttp/web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,13 @@
from typing_extensions import final

from . import hdrs
from .abc import AbstractAccessLogger, AbstractStreamWriter
from .frozenlist import FrozenList
from .helpers import get_running_loop
from .http_parser import RawRequestMessage
from .log import web_logger
from .signals import Signal
from .streams import StreamReader
from .web_log import AccessLogger
from .web_middlewares import _fix_request_current_app
from .web_protocol import RequestHandler
from .web_request import Request
from .web_response import StreamResponse
from .web_routedef import AbstractRouteDef
from .web_server import Server
from .web_urldispatcher import (
AbstractResource,
Domain,
Expand Down Expand Up @@ -290,44 +283,6 @@ def router(self) -> UrlDispatcher:
def middlewares(self) -> _Middlewares:
return self._middlewares

def _make_handler(self, *,
loop: Optional[asyncio.AbstractEventLoop]=None,
access_log_class: Type[
AbstractAccessLogger]=AccessLogger,
**kwargs: Any) -> Server:

if not issubclass(access_log_class, AbstractAccessLogger):
raise TypeError(
'access_log_class must be subclass of '
'aiohttp.abc.AbstractAccessLogger, got {}'.format(
access_log_class))

self.freeze()

kwargs['access_log_class'] = access_log_class
if self._handler_args:
for k, v in self._handler_args.items():
kwargs[k] = v

return Server(self._handle, # type: ignore
request_factory=self._make_request,
**kwargs)

def make_handler(self, *,
loop: Optional[asyncio.AbstractEventLoop]=None,
access_log_class: Type[
AbstractAccessLogger]=AccessLogger,
**kwargs: Any) -> Server:

warnings.warn("Application.make_handler(...) is deprecated, "
"use AppRunner API instead",
DeprecationWarning,
stacklevel=2)

return self._make_handler(loop=loop,
access_log_class=access_log_class,
**kwargs)

async def startup(self) -> None:
"""Causes on_startup signal

Expand All @@ -349,18 +304,6 @@ async def cleanup(self) -> None:
"""
await self.on_cleanup.send(self)

def _make_request(self, message: RawRequestMessage,
payload: StreamReader,
protocol: RequestHandler,
writer: AbstractStreamWriter,
task: 'asyncio.Task[None]',
_cls: Type[Request]=Request) -> Request:
loop = get_running_loop()
return _cls(
message, payload, protocol, writer, task,
loop,
client_max_size=self._client_max_size)

def _prepare_middleware(self) -> Iterator[_Middleware]:
yield from reversed(self._middlewares)
yield _fix_request_current_app(self)
Expand Down
46 changes: 41 additions & 5 deletions aiohttp/web_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@
import signal
import socket
from abc import ABC, abstractmethod
from typing import Any, List, Optional, Set
from typing import Any, List, Optional, Set, Type

from yarl import URL

from .abc import AbstractAccessLogger, AbstractStreamWriter
from .helpers import get_running_loop
from .http_parser import RawRequestMessage
from .streams import StreamReader
from .web_app import Application
from .web_log import AccessLogger
from .web_protocol import RequestHandler
from .web_request import Request
from .web_server import Server

try:
Expand Down Expand Up @@ -310,11 +317,27 @@ class AppRunner(BaseRunner):
__slots__ = ('_app',)

def __init__(self, app: Application, *,
handle_signals: bool=False, **kwargs: Any) -> None:
super().__init__(handle_signals=handle_signals, **kwargs)
handle_signals: bool=False,
access_log_class: Type[
AbstractAccessLogger]=AccessLogger,
**kwargs: Any) -> None:

if not isinstance(app, Application):
raise TypeError("The first argument should be web.Application "
"instance, got {!r}".format(app))
kwargs['access_log_class'] = access_log_class

if app._handler_args:
for k, v in app._handler_args.items():
kwargs[k] = v

if not issubclass(kwargs['access_log_class'], AbstractAccessLogger):
raise TypeError(
'access_log_class must be subclass of '
'aiohttp.abc.AbstractAccessLogger, got {}'.format(
kwargs['access_log_class']))

super().__init__(handle_signals=handle_signals, **kwargs)
self._app = app

@property
Expand All @@ -325,12 +348,25 @@ async def shutdown(self) -> None:
await self._app.shutdown()

async def _make_server(self) -> Server:
loop = asyncio.get_event_loop()
self._app.on_startup.freeze()
await self._app.startup()
self._app.freeze()

return self._app._make_handler(loop=loop, **self._kwargs)
return Server(self._app._handle, # type: ignore
request_factory=self._make_request,
**self._kwargs)

def _make_request(self, message: RawRequestMessage,
payload: StreamReader,
protocol: RequestHandler,
writer: AbstractStreamWriter,
task: 'asyncio.Task[None]',
_cls: Type[Request]=Request) -> Request:
loop = get_running_loop()
return _cls(
message, payload, protocol, writer, task,
loop,
client_max_size=self.app._client_max_size)

async def _cleanup_server(self) -> None:
await self._app.cleanup()
2 changes: 1 addition & 1 deletion docs/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Pytest tooling has the following fixtures:
.. versionadded:: 3.0

*kwargs* are parameters passed to
:meth:`aiohttp.web.Application.make_handler`
:meth:`aiohttp.web.AppRunner`

.. versionchanged:: 3.0
.. deprecated:: 3.2
Expand Down
82 changes: 28 additions & 54 deletions docs/web_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ duplicated like one using :meth:`Application.copy`.
:ref:`aiohttp-web-middlewares` for details.

:param handler_args: dict-like object that overrides keyword arguments of
:meth:`Application.make_handler`
:class:`AppRunner` constructor.

:param client_max_size: client's maximum size in a request, in
bytes. If a POST request exceeds this
Expand All @@ -1258,6 +1258,7 @@ duplicated like one using :meth:`Application.copy`.
The argument does nothing starting from 4.0,
use asyncio :ref:`asyncio-debug-mode` instead.


.. attribute:: router

Read-only property that returns *router instance*.
Expand Down Expand Up @@ -1391,59 +1392,6 @@ duplicated like one using :meth:`Application.copy`.

.. versionadded:: 3.1

.. method:: make_handler(loop=None, **kwargs)

Creates HTTP protocol factory for handling requests.

:param loop: :ref:`event loop<asyncio-event-loop>` used
for processing HTTP requests.

If param is ``None`` :func:`asyncio.get_event_loop`
used for getting default event loop.

.. deprecated:: 2.0

:param bool tcp_keepalive: Enable TCP Keep-Alive. Default: ``True``.
:param int keepalive_timeout: Number of seconds before closing Keep-Alive
connection. Default: ``75`` seconds (NGINX's default value).
:param logger: Custom logger object. Default:
:data:`aiohttp.log.server_logger`.
:param access_log: Custom logging object. Default:
:data:`aiohttp.log.access_logger`.
:param access_log_class: Class for `access_logger`. Default:
:data:`aiohttp.helpers.AccessLogger`.
Must to be a subclass of :class:`aiohttp.abc.AbstractAccessLogger`.
:param str access_log_format: Access log format string. Default:
:attr:`helpers.AccessLogger.LOG_FORMAT`.
:param int max_line_size: Optional maximum header line size. Default:
``8190``.
:param int max_headers: Optional maximum header size. Default: ``32768``.
:param int max_field_size: Optional maximum header field size. Default:
``8190``.

:param float lingering_time: Maximum time during which the server
reads and ignores additional data coming from the client when
lingering close is on. Use ``0`` to disable lingering on
server channel closing.

You should pass result of the method as *protocol_factory* to
:meth:`~asyncio.AbstractEventLoop.create_server`, e.g.::

loop = asyncio.get_event_loop()

app = Application()

# setup route table
# app.router.add_route(...)

await loop.create_server(app.make_handler(),
'0.0.0.0', 8080)

.. deprecated:: 3.2

The method is deprecated and will be removed in future
aiohttp versions. Please use :ref:`aiohttp-web-app-runners` instead.

.. comethod:: startup()

A :ref:`coroutine<coroutine>` that will be called along with the
Expand Down Expand Up @@ -2490,6 +2438,32 @@ application on specific TCP or Unix socket, e.g.::
:param kwargs: named parameters to pass into
web protocol.

Supported *kwargs*:

:param bool tcp_keepalive: Enable TCP Keep-Alive. Default: ``True``.
:param int keepalive_timeout: Number of seconds before closing Keep-Alive
connection. Default: ``75`` seconds (NGINX's default value).
:param logger: Custom logger object. Default:
:data:`aiohttp.log.server_logger`.
:param access_log: Custom logging object. Default:
:data:`aiohttp.log.access_logger`.
:param access_log_class: Class for `access_logger`. Default:
:data:`aiohttp.helpers.AccessLogger`.
Must to be a subclass of :class:`aiohttp.abc.AbstractAccessLogger`.
:param str access_log_format: Access log format string. Default:
:attr:`helpers.AccessLogger.LOG_FORMAT`.
:param int max_line_size: Optional maximum header line size. Default:
``8190``.
:param int max_headers: Optional maximum header size. Default: ``32768``.
:param int max_field_size: Optional maximum header field size. Default:
``8190``.

:param float lingering_time: Maximum time during which the server
reads and ignores additional data coming from the client when
lingering close is on. Use ``0`` to disable lingering on
server channel closing.


.. attribute:: app

Read-only attribute for accessing to :class:`Application` served
Expand Down
64 changes: 0 additions & 64 deletions tests/test_web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from async_generator import async_generator, yield_

from aiohttp import log, web
from aiohttp.abc import AbstractAccessLogger
from aiohttp.helpers import PY_36
from aiohttp.test_utils import make_mocked_coro

Expand All @@ -20,69 +19,6 @@ def test_app_call() -> None:
assert app is app()


@pytest.mark.parametrize('debug', [True, False])
async def test_app_make_handler_debug_exc(mocker, debug) -> None:
loop = asyncio.get_event_loop()
loop.set_debug(debug)
with pytest.warns(DeprecationWarning):
app = web.Application(debug=debug)
srv = mocker.patch('aiohttp.web_app.Server')

with pytest.warns(DeprecationWarning):
assert app.debug == debug

app._make_handler()
srv.assert_called_with(app._handle,
request_factory=app._make_request,
access_log_class=mock.ANY)


async def test_app_make_handler_args(mocker) -> None:
app = web.Application(handler_args={'test': True})
srv = mocker.patch('aiohttp.web_app.Server')

app._make_handler()
srv.assert_called_with(app._handle,
request_factory=app._make_request,
access_log_class=mock.ANY,
test=True)


async def test_app_make_handler_access_log_class(mocker) -> None:
class Logger:
pass

app = web.Application()

with pytest.raises(TypeError):
app._make_handler(access_log_class=Logger)

class Logger(AbstractAccessLogger):

def log(self, request, response, time):
self.logger.info('msg')

srv = mocker.patch('aiohttp.web_app.Server')

app._make_handler(access_log_class=Logger)
srv.assert_called_with(app._handle,
access_log_class=Logger,
request_factory=app._make_request)

app = web.Application(handler_args={'access_log_class': Logger})
app._make_handler(access_log_class=Logger)
srv.assert_called_with(app._handle,
access_log_class=Logger,
request_factory=app._make_request)


async def test_app_make_handler_raises_deprecation_warning() -> None:
app = web.Application()

with pytest.warns(DeprecationWarning):
app.make_handler()


async def test_app_register_on_finish() -> None:
app = web.Application()
cb1 = make_mocked_coro(None)
Expand Down
Loading