Repository: aio-libs/aiohttp

Issue:
Cannot have python keyword in route name
🐞 **Describe the bug**
<!-- A clear and concise description of what the bug is, on the next line. -->
This code is rejected with 'Incorrect route name':
```python
@app_routes.get('/result/', name='check-for-result')
async def result(request):
```

This is because 'for' is a keyword, and the check rejects any keywords for some strange reason:
in https://github.com/aio-libs/aiohttp/blob/master/aiohttp/web_urldispatcher.py#L982
```python
parts = self.NAME_SPLIT_RE.split(name)
for part in parts:
      if not part.isidentifier() or keyword.iskeyword(part):
           raise ValueError
```
I think the intention was to have:
```python
if not (part.isidentifier() or keyword.iskeyword(part))
```

💡 **To Reproduce**
<!-- How to reproduce the behavior?

For example:
1. Have certain environment
2. Run given code snippet in a certain way
3. See some behavior described

Add these steps below this comment: -->


💡 **Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
Should accept route names containing python keywords

📋 **Logs/tracebacks**
<!-- If applicable, add logs/tracebacks to help explain your problem. -->
```python-traceback (paste your traceback in the next line)

```

📋 **Your version of the Python**
<!-- Attach your version of the Python. -->
```console
$ python --version
Python 3.7.4
```

📋 **Your version of the aiohttp/yarl/multidict distributions**
<!-- Attach your version of the distributions in the code blocks below. -->
```console
$ python -m pip show aiohttp
Version: 3.6.2
```
```console
$ python -m pip show multidict
Version: 4.7.5
```
```console
$ python -m pip show yarl
Version: 1.3.0
```

📋 **Additional context**
<!-- Add any other context about the problem here, in the next line. -->

<!-- Describe the environment you have that lead to your issue.
     This includes aiohttp version, OS, proxy server and other bits that
     are related to your case.

     IMPORTANT: aiohttp is both server framework and client library.
     For getting rid of confusing please put 'server', 'client' or 'both'
     word here.
     -->



Discussion:
Please fill out the issue template.

Resolving patch:
diff --git a/aiohttp/web_urldispatcher.py b/aiohttp/web_urldispatcher.py
--- a/aiohttp/web_urldispatcher.py
+++ b/aiohttp/web_urldispatcher.py
@@ -981,7 +981,11 @@ def register_resource(self, resource: AbstractResource) -> None:
         if name is not None:
             parts = self.NAME_SPLIT_RE.split(name)
             for part in parts:
-                if not part.isidentifier() or keyword.iskeyword(part):
+                if keyword.iskeyword(part):
+                    raise ValueError(f'Incorrect route name {name!r}, '
+                                     'python keywords cannot be used '
+                                     'for route name')
+                if not part.isidentifier():
                     raise ValueError('Incorrect route name {!r}, '
                                      'the name should be a sequence of '
                                      'python identifiers separated '


Test patch:
diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py
--- a/tests/test_urldispatch.py
+++ b/tests/test_urldispatch.py
@@ -1150,6 +1150,11 @@ def test_invalid_route_name(router) -> None:
         router.add_get('/', make_handler(), name='invalid name')
 
 
+def test_invalid_route_name(router) -> None:
+    with pytest.raises(ValueError):
+        router.add_get('/', make_handler(), name='class')  # identifier
+
+
 def test_frozen_router(router) -> None:
     router.freeze()
     with pytest.raises(RuntimeError):