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

Expose named routes via UrlDispatcher.named_routes() #622

Merged
merged 1 commit into from
Nov 5, 2015
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
4 changes: 4 additions & 0 deletions aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from collections.abc import Sized, Iterable, Container
from urllib.parse import urlencode, unquote
from types import MappingProxyType

from . import hdrs
from .abc import AbstractRouter, AbstractMatchInfo
Expand Down Expand Up @@ -440,6 +441,9 @@ def __getitem__(self, name):
def routes(self):
return RoutesView(self._urls)

def named_routes(self):
return MappingProxyType(self._routes)

def register_route(self, route):
assert isinstance(route, Route), 'Instance of Route class is required.'

Expand Down
21 changes: 21 additions & 0 deletions docs/web_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,27 @@ Router is any object that implements :class:`AbstractRouter` interface.

.. versionadded:: 0.18

.. method:: named_routes()

Returns a :obj:`dict`-like :class:`types.MappingProxyType` *view* over
*all* named routes.

The view maps every named route's :attr:`Route.name` attribute to the
:class:`Route`. It supports the usual :obj:`dict`-like operations, except
for any mutable operations (i.e. it's **read-only**)::

len(app.router.named_routes())

for name, route in app.router.named_routes().items():
print(name, route)

"route_name" in app.router.named_routes()

app.router.named_routes()["route_name"]

.. versionadded:: 0.19


.. _aiohttp-web-route:

Route
Expand Down
25 changes: 24 additions & 1 deletion tests/test_urldispatch.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import asyncio
import os
import unittest
from collections.abc import Sized, Container, Iterable
from collections.abc import Sized, Container, Iterable, Mapping, MutableMapping
from unittest import mock
from urllib.parse import unquote
import aiohttp.web
Expand Down Expand Up @@ -642,3 +642,26 @@ def test_routes_abc(self):
self.assertIsInstance(self.router.routes(), Sized)
self.assertIsInstance(self.router.routes(), Iterable)
self.assertIsInstance(self.router.routes(), Container)

def fill_named_routes(self):
route1 = self.router.add_route('GET', '/plain', self.make_handler(),
name='route1')
route2 = self.router.add_route('GET', '/variable/{name}',
self.make_handler(), name='route2')
route3 = self.router.add_static('/static',
os.path.dirname(aiohttp.__file__),
name='route3')
return route1, route2, route3

def test_named_routes_abc(self):
self.assertIsInstance(self.router.named_routes(), Mapping)
self.assertNotIsInstance(self.router.named_routes(), MutableMapping)

def test_named_routes(self):
named_routes = self.fill_named_routes()

self.assertEqual(3, len(self.router.named_routes()))

for route in named_routes:
self.assertIn(route.name, self.router.named_routes())
self.assertEqual(route, self.router.named_routes()[route.name])