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

[3.6] UrlDispatcher - add_routes returns a list of AbstractRoutes (#4141) #4233

Merged
merged 1 commit into from
Oct 18, 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
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