diff --git a/sanic/router.py b/sanic/router.py index 2864bf84..8ddba1a3 100644 --- a/sanic/router.py +++ b/sanic/router.py @@ -38,6 +38,10 @@ class RouteDoesNotExist(Exception): pass +class ParameterNameConflicts(Exception): + pass + + class Router: """Router supports basic routing with parameters and method checks @@ -195,12 +199,19 @@ class Router: methods = frozenset(methods) parameters = [] + parameter_names = set() properties = {"unhashable": None} def add_parameter(match): name = match.group(1) name, _type, pattern = self.parse_parameter_string(name) + if name in parameter_names: + raise ParameterNameConflicts( + "Multiple parameter named <{name}> " + "in route uri {uri}".format(name=name, uri=uri)) + parameter_names.add(name) + parameter = Parameter( name=name, cast=_type) parameters.append(parameter) diff --git a/setup.py b/setup.py index 027918bc..5e5eb2de 100644 --- a/setup.py +++ b/setup.py @@ -48,6 +48,7 @@ setup_kwargs = { 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', ], } diff --git a/tests/test_routes.py b/tests/test_routes.py index d5f1c90a..ac0b4bf6 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -3,7 +3,7 @@ import pytest from sanic import Sanic from sanic.response import text, json -from sanic.router import RouteExists, RouteDoesNotExist +from sanic.router import RouteExists, RouteDoesNotExist, ParameterNameConflicts from sanic.constants import HTTP_METHODS @@ -935,3 +935,10 @@ def test_uri_with_different_method_and_different_params(app): assert response.json == { 'action': 'post' } + + +def test_route_raise_ParameterNameConflicts(app): + with pytest.raises(ParameterNameConflicts): + @app.get('/api/v1///') + def handler(request, user): + return text('OK')