Skip to content

Commit

Permalink
[3.6] UrlDispatcher - add_routes returns a list of AbstractRoutes (#4141
Browse files Browse the repository at this point in the history
)

Co-Authored-By: Andrew Svetlov <andrew.svetlov@gmail.com>.
(cherry picked from commit 60e6c22)

Co-authored-by: Zlatan <zlatan.sicanica@gmail.com>
  • Loading branch information
zlatsic authored and asvetlov committed Oct 18, 2019
1 parent 2d8f62b commit e95a2f0
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 16 deletions.
3 changes: 3 additions & 0 deletions CHANGES/3866.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
`web.UrlDispatcher.add_routes` and `web.Application.add_routes` return a list
of registered `AbstractRoute` instances. `AbstractRouteDef.register` (and all
subclasses) return a list of registered resources registered resource.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -271,5 +271,6 @@ Young-Ho Cha
Yuriy Shatrov
Yury Selivanov
Yusuke Tsutsumi
Zlatan Sičanica
Марк Коренберг
Семён Марьясин
6 changes: 4 additions & 2 deletions aiohttp/web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
from .web_server import Server
from .web_urldispatcher import (
AbstractResource,
AbstractRoute,
Domain,
MaskDomain,
MatchedSubAppResource,
Expand Down Expand Up @@ -310,8 +311,9 @@ def add_domain(self, domain: str,
factory = partial(MatchedSubAppResource, rule, subapp)
return self._add_subapp(factory, subapp)

def add_routes(self, routes: Iterable[AbstractRouteDef]) -> None:
self.router.add_routes(routes)
def add_routes(self,
routes: Iterable[AbstractRouteDef]) -> List[AbstractRoute]:
return self.router.add_routes(routes)

@property
def on_response_prepare(self) -> _RespPrepareSignal:
Expand Down
23 changes: 14 additions & 9 deletions aiohttp/web_routedef.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
from .typedefs import PathLike

if TYPE_CHECKING: # pragma: no cover
from .web_urldispatcher import UrlDispatcher
from .web_urldispatcher import (
UrlDispatcher,
AbstractRoute
)
from .web_request import Request
from .web_response import StreamResponse
else:
Request = StreamResponse = UrlDispatcher = None
Request = StreamResponse = UrlDispatcher = AbstractRoute = None


__all__ = ('AbstractRouteDef', 'RouteDef', 'StaticDef', 'RouteTableDef',
Expand All @@ -36,7 +39,7 @@

class AbstractRouteDef(abc.ABC):
@abc.abstractmethod
def register(self, router: UrlDispatcher) -> None:
def register(self, router: UrlDispatcher) -> List[AbstractRoute]:
pass # pragma: no cover


Expand All @@ -59,13 +62,13 @@ def __repr__(self) -> str:
"{info}>".format(method=self.method, path=self.path,
handler=self.handler, info=''.join(info)))

def register(self, router: UrlDispatcher) -> None:
def register(self, router: UrlDispatcher) -> List[AbstractRoute]:
if self.method in hdrs.METH_ALL:
reg = getattr(router, 'add_'+self.method.lower())
reg(self.path, self.handler, **self.kwargs)
return [reg(self.path, self.handler, **self.kwargs)]
else:
router.add_route(self.method, self.path, self.handler,
**self.kwargs)
return [router.add_route(self.method, self.path, self.handler,
**self.kwargs)]


@attr.s(frozen=True, repr=False, slots=True)
Expand All @@ -82,8 +85,10 @@ def __repr__(self) -> str:
"{info}>".format(prefix=self.prefix, path=self.path,
info=''.join(info)))

def register(self, router: UrlDispatcher) -> None:
router.add_static(self.prefix, self.path, **self.kwargs)
def register(self, router: UrlDispatcher) -> List[AbstractRoute]:
resource = router.add_static(self.prefix, self.path, **self.kwargs)
routes = resource.get_info().get('routes', {})
return routes.values()


def route(method: str, path: str, handler: _HandlerType,
Expand Down
12 changes: 9 additions & 3 deletions aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,8 @@ def _get_file_hash(byte_array: bytes) -> str:

def get_info(self) -> Dict[str, Any]:
return {'directory': self._directory,
'prefix': self._prefix}
'prefix': self._prefix,
'routes': self._routes}

def set_options_route(self, handler: _WebHandler) -> None:
if 'OPTIONS' in self._routes:
Expand Down Expand Up @@ -1126,10 +1127,15 @@ def freeze(self) -> None:
for resource in self._resources:
resource.freeze()

def add_routes(self, routes: Iterable[AbstractRouteDef]) -> None:
def add_routes(self,
routes: Iterable[AbstractRouteDef]) -> List[AbstractRoute]:
"""Append routes to route table.
Parameter should be a sequence of RouteDef objects.
Returns a list of registered AbstractRoute instances.
"""
registered_routes = []
for route_def in routes:
route_def.register(self)
registered_routes.extend(route_def.register(self))
return registered_routes
21 changes: 21 additions & 0 deletions docs/web_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1460,12 +1460,19 @@ duplicated like one using :meth:`Application.copy`.
The table is a :class:`list` of :class:`RouteDef` items or
:class:`RouteTableDef`.

:returns: :class:`list` of registered :class:`AbstractRoute` instances.

The method is a shortcut for
``app.router.add_routes(routes_table)``, see also
:meth:`UrlDispatcher.add_routes`.

.. versionadded:: 3.1

.. versionchanged:: 3.7

Return value updated from ``None`` to :class:`list` of
:class:`AbstractRoute` instances.

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

Creates HTTP protocol factory for handling requests.
Expand Down Expand Up @@ -1669,8 +1676,15 @@ Router is any object that implements :class:`AbstractRouter` interface.
The table is a :class:`list` of :class:`RouteDef` items or
:class:`RouteTableDef`.

:returns: :class:`list` of registered :class:`AbstractRoute` instances.

.. versionadded:: 2.3

.. versionchanged:: 3.7

Return value updated from ``None`` to :class:`list` of
:class:`AbstractRoute` instances.

.. method:: add_get(path, handler, *, name=None, allow_head=True, **kwargs)

Shortcut for adding a GET handler. Calls the :meth:`add_route` with \
Expand Down Expand Up @@ -2180,6 +2194,13 @@ The definition is created by functions like :func:`get` or

Abstract method, should be overridden by subclasses.

:returns: :class:`list` of registered :class:`AbstractRoute` objects.

.. versionchanged:: 3.7

Return value updated from ``None`` to :class:`list` of
:class:`AbstractRoute` instances.


.. class:: RouteDef

Expand Down
7 changes: 5 additions & 2 deletions tests/test_urldispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -903,8 +903,11 @@ async def test_match_info_get_info_dynamic2(router) -> None:
def test_static_resource_get_info(router) -> None:
directory = pathlib.Path(aiohttp.__file__).parent.resolve()
resource = router.add_static('/st', directory)
assert resource.get_info() == {'directory': directory,
'prefix': '/st'}
info = resource.get_info()
assert len(info) == 3
assert info['directory'] == directory
assert info['prefix'] == '/st'
assert all([type(r) is ResourceRoute for r in info['routes'].values()])


async def test_system_route_get_info(router) -> None:
Expand Down

0 comments on commit e95a2f0

Please sign in to comment.