Skip to content

Commit

Permalink
Merge master.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dreamsorcerer committed Jul 17, 2021
2 parents 2d99255 + e3dcc71 commit ed1e383
Show file tree
Hide file tree
Showing 24 changed files with 94 additions and 79 deletions.
3 changes: 0 additions & 3 deletions .mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ warn_unused_ignores = True
disallow_any_unimported = True
warn_return_any = True

[mypy-tests.*]
disallow_untyped_defs = False

[mypy-aiodns]
ignore_missing_imports = True

Expand Down
1 change: 1 addition & 0 deletions CHANGES/3450.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Started using `MultiLoopChildWatcher` when it's available under POSIX while setting up the test I/O loop.
1 change: 1 addition & 0 deletions CHANGES/4686.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a request handler type alias ``aiohttp.typedefs.Handler``.
1 change: 1 addition & 0 deletions CHANGES/5829.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Disallow untyped defs on internal tests.
1 change: 1 addition & 0 deletions CHANGES/5836.doc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix the `ClientResponse.release`'s type in the doc. Change from `comethod` to `method`.
2 changes: 2 additions & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Anton Zhdan-Pushkin
Arseny Timoniq
Artem Yushkovskiy
Arthur Darcet
Austin Scola
Ben Bader
Ben Timby
Benedikt Reinartz
Expand Down Expand Up @@ -240,6 +241,7 @@ Pawel Miech
Pepe Osca
Philipp A.
Pieter van Beek
Qiao Han
Rafael Viotti
Raphael Bialon
Raúl Cumplido
Expand Down
11 changes: 10 additions & 1 deletion aiohttp/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,16 @@ def setup_test_loop(
asyncio.set_event_loop(loop)
if sys.platform != "win32" and not skip_watcher:
policy = asyncio.get_event_loop_policy()
watcher = asyncio.SafeChildWatcher()
watcher: asyncio.AbstractChildWatcher
try: # Python >= 3.8
# Refs:
# * https://github.com/pytest-dev/pytest-xdist/issues/620
# * https://stackoverflow.com/a/58614689/595220
# * https://bugs.python.org/issue35621
# * https://github.com/python/cpython/pull/14344
watcher = asyncio.MultiLoopChildWatcher()
except AttributeError: # Python < 3.8
watcher = asyncio.SafeChildWatcher()
watcher.attach_loop(loop)
with contextlib.suppress(NotImplementedError):
policy.set_child_watcher(watcher)
Expand Down
14 changes: 13 additions & 1 deletion aiohttp/typedefs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import json
import os
from typing import TYPE_CHECKING, Any, Callable, Iterable, Mapping, Tuple, Union
from typing import (
TYPE_CHECKING,
Any,
Awaitable,
Callable,
Iterable,
Mapping,
Tuple,
Union,
)

from multidict import CIMultiDict, CIMultiDictProxy, MultiDict, MultiDictProxy, istr
from yarl import URL
Expand All @@ -14,6 +23,8 @@
_MultiDict = MultiDict[str]
_MultiDictProxy = MultiDictProxy[str]
from http.cookies import BaseCookie, Morsel

from .web import Request, StreamResponse
else:
_CIMultiDict = CIMultiDict
_CIMultiDictProxy = CIMultiDictProxy
Expand All @@ -37,5 +48,6 @@
"BaseCookie[str]",
]

Handler = Callable[["Request"], Awaitable["StreamResponse"]]

PathLike = Union[str, "os.PathLike[str]"]
5 changes: 3 additions & 2 deletions aiohttp/web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,11 @@


if TYPE_CHECKING: # pragma: no cover
from .typedefs import Handler

_AppSignal = Signal[Callable[["Application"], Awaitable[None]]]
_RespPrepareSignal = Signal[Callable[[Request, StreamResponse], Awaitable[None]]]
_Handler = Callable[[Request], Awaitable[StreamResponse]]
_Middleware = Callable[[Request, _Handler], Awaitable[StreamResponse]]
_Middleware = Callable[[Request, Handler], Awaitable[StreamResponse]]
_Middlewares = FrozenList[_Middleware]
_MiddlewaresHandlers = Sequence[_Middleware]
_Subapps = List["Application"]
Expand Down
8 changes: 4 additions & 4 deletions aiohttp/web_middlewares.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import warnings
from typing import TYPE_CHECKING, Awaitable, Callable, Tuple, Type, TypeVar

from .typedefs import Handler
from .web_exceptions import HTTPMove, HTTPPermanentRedirect
from .web_request import Request
from .web_response import StreamResponse
Expand Down Expand Up @@ -41,8 +42,7 @@ def middleware(f: _Func) -> _Func:
return f


_Handler = Callable[[Request], Awaitable[StreamResponse]]
_Middleware = Callable[[Request, _Handler], Awaitable[StreamResponse]]
_Middleware = Callable[[Request, Handler], Awaitable[StreamResponse]]


def normalize_path_middleware(
Expand Down Expand Up @@ -85,7 +85,7 @@ def normalize_path_middleware(
correct_configuration = not (append_slash and remove_slash)
assert correct_configuration, "Cannot both remove and append slash"

async def impl(request: Request, handler: _Handler) -> StreamResponse:
async def impl(request: Request, handler: Handler) -> StreamResponse:
if isinstance(request.match_info.route, SystemRoute):
paths_to_check = []
if "?" in request.raw_path:
Expand Down Expand Up @@ -119,7 +119,7 @@ async def impl(request: Request, handler: _Handler) -> StreamResponse:


def _fix_request_current_app(app: "Application") -> _Middleware:
async def impl(request: Request, handler: _Handler) -> StreamResponse:
async def impl(request: Request, handler: Handler) -> StreamResponse:
with request.match_info.set_current_app(app):
return await handler(request)

Expand Down
6 changes: 2 additions & 4 deletions aiohttp/web_routedef.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from typing import (
TYPE_CHECKING,
Any,
Awaitable,
Callable,
Dict,
Iterator,
Expand All @@ -18,7 +17,7 @@

from . import hdrs
from .abc import AbstractView
from .typedefs import PathLike
from .typedefs import Handler, PathLike

if TYPE_CHECKING: # pragma: no cover
from .web_request import Request
Expand Down Expand Up @@ -52,8 +51,7 @@ def register(self, router: UrlDispatcher) -> List[AbstractRoute]:
pass # pragma: no cover


_SimpleHandler = Callable[[Request], Awaitable[StreamResponse]]
_HandlerType = Union[Type[AbstractView], _SimpleHandler]
_HandlerType = Union[Type[AbstractView], Handler]


@dataclasses.dataclass(frozen=True, repr=False)
Expand Down
37 changes: 15 additions & 22 deletions aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from .abc import AbstractMatchInfo, AbstractRouter, AbstractView
from .helpers import DEBUG, iscoroutinefunction
from .http import HttpVersion11
from .typedefs import PathLike
from .typedefs import Handler, PathLike
from .web_exceptions import (
HTTPException,
HTTPExpectationFailed,
Expand Down Expand Up @@ -81,7 +81,6 @@
PATH_SEP: Final[str] = re.escape("/")


_WebHandler = Callable[[Request], Awaitable[StreamResponse]]
_ExpectHandler = Callable[[Request], Awaitable[None]]
_Resolve = Tuple[Optional[AbstractMatchInfo], Set[str]]

Expand Down Expand Up @@ -156,7 +155,7 @@ class AbstractRoute(abc.ABC):
def __init__(
self,
method: str,
handler: Union[_WebHandler, Type[AbstractView]],
handler: Union[Handler, Type[AbstractView]],
*,
expect_handler: Optional[_ExpectHandler] = None,
resource: Optional[AbstractResource] = None,
Expand Down Expand Up @@ -193,7 +192,7 @@ def method(self) -> str:
return self._method

@property
def handler(self) -> _WebHandler:
def handler(self) -> Handler:
return self._handler

@property
Expand Down Expand Up @@ -226,7 +225,7 @@ def __init__(self, match_dict: Dict[str, str], route: AbstractRoute):
self._frozen = False

@property
def handler(self) -> _WebHandler:
def handler(self) -> Handler:
return self._route.handler

@property
Expand Down Expand Up @@ -321,7 +320,7 @@ def __init__(self, *, name: Optional[str] = None) -> None:
def add_route(
self,
method: str,
handler: Union[Type[AbstractView], _WebHandler],
handler: Union[Type[AbstractView], Handler],
*,
expect_handler: Optional[_ExpectHandler] = None,
) -> "ResourceRoute":
Expand Down Expand Up @@ -606,7 +605,7 @@ def get_info(self) -> _InfoDict:
"routes": self._routes,
}

def set_options_route(self, handler: _WebHandler) -> None:
def set_options_route(self, handler: Handler) -> None:
if "OPTIONS" in self._routes:
raise RuntimeError("OPTIONS route was set already")
self._routes["OPTIONS"] = ResourceRoute(
Expand Down Expand Up @@ -863,7 +862,7 @@ class ResourceRoute(AbstractRoute):
def __init__(
self,
method: str,
handler: Union[_WebHandler, Type[AbstractView]],
handler: Union[Handler, Type[AbstractView]],
resource: AbstractResource,
*,
expect_handler: Optional[_ExpectHandler] = None,
Expand Down Expand Up @@ -1073,7 +1072,7 @@ def add_route(
self,
method: str,
path: str,
handler: Union[_WebHandler, Type[AbstractView]],
handler: Union[Handler, Type[AbstractView]],
*,
name: Optional[str] = None,
expect_handler: Optional[_ExpectHandler] = None,
Expand Down Expand Up @@ -1115,15 +1114,13 @@ def add_static(
self.register_resource(resource)
return resource

def add_head(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute:
def add_head(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method HEAD
"""
return self.add_route(hdrs.METH_HEAD, path, handler, **kwargs)

def add_options(
self, path: str, handler: _WebHandler, **kwargs: Any
) -> AbstractRoute:
def add_options(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method OPTIONS
"""
Expand All @@ -1132,7 +1129,7 @@ def add_options(
def add_get(
self,
path: str,
handler: _WebHandler,
handler: Handler,
*,
name: Optional[str] = None,
allow_head: bool = True,
Expand All @@ -1147,29 +1144,25 @@ def add_get(
resource.add_route(hdrs.METH_HEAD, handler, **kwargs)
return resource.add_route(hdrs.METH_GET, handler, **kwargs)

def add_post(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute:
def add_post(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method POST
"""
return self.add_route(hdrs.METH_POST, path, handler, **kwargs)

def add_put(self, path: str, handler: _WebHandler, **kwargs: Any) -> AbstractRoute:
def add_put(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method PUT
"""
return self.add_route(hdrs.METH_PUT, path, handler, **kwargs)

def add_patch(
self, path: str, handler: _WebHandler, **kwargs: Any
) -> AbstractRoute:
def add_patch(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method PATCH
"""
return self.add_route(hdrs.METH_PATCH, path, handler, **kwargs)

def add_delete(
self, path: str, handler: _WebHandler, **kwargs: Any
) -> AbstractRoute:
def add_delete(self, path: str, handler: Handler, **kwargs: Any) -> AbstractRoute:
"""
Shortcut for add_route with method DELETE
"""
Expand Down
1 change: 1 addition & 0 deletions docs/built_with.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ project, pointing to `<https://github.com/aio-libs/aiohttp>`_.
* `Mariner <https://gitlab.com/radek-sprta/mariner>`_ Command-line torrent searcher.
* `DEEPaaS API <https://github.com/indigo-dc/DEEPaaS>`_ REST API for Machine learning, Deep learning and artificial intelligence applications.
* `BentoML <https://github.com/bentoml/BentoML>`_ Machine Learning model serving framework
* `salted <https://github.com/RuedigerVoigt/salted>`_ fast link check library (for HTML, Markdown, LaTeX, ...) with CLI
4 changes: 2 additions & 2 deletions docs/client_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1225,7 +1225,7 @@ Response object
assert resp.status == 200

After exiting from ``async with`` block response object will be
*released* (see :meth:`release` coroutine).
*released* (see :meth:`release` method).

.. attribute:: version

Expand Down Expand Up @@ -1354,7 +1354,7 @@ Response object

.. seealso:: :meth:`close`, :meth:`release`.

.. comethod:: release()
.. method:: release()

It is not required to call `release` on the response
object. When the client fully receives the payload, the
Expand Down
3 changes: 0 additions & 3 deletions docs/third_party.rst
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,6 @@ period ask to raise the status.
popular web frameworks, including Flask, Django, Bottle, Tornado,
Pyramid, webapp2, Falcon, and aiohttp.

- `aioauth-client <https://github.com/klen/aioauth-client>`_ OAuth
client for aiohttp.

- `aiohttpretty
<https://github.com/CenterForOpenScience/aiohttpretty>`_ A simple
asyncio compatible httpretty mock using aiohttp.
Expand Down
7 changes: 2 additions & 5 deletions examples/web_rewrite_headers_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@
"""
Example for rewriting response headers by middleware.
"""
from typing import Awaitable, Callable

from aiohttp import web

_WebHandler = Callable[[web.Request], Awaitable[web.StreamResponse]]
from aiohttp.typedefs import Handler


async def handler(request: web.Request) -> web.StreamResponse:
return web.Response(text="Everything is fine")


async def middleware(request: web.Request, handler: _WebHandler) -> web.StreamResponse:
async def middleware(request: web.Request, handler: Handler) -> web.StreamResponse:
try:
response = await handler(request)
except web.HTTPException as exc:
Expand Down
Loading

0 comments on commit ed1e383

Please sign in to comment.