@@ -350,7 +350,9 @@ async def _default_expect_handler(request: Request) -> None:
350
350
class Resource (AbstractResource ):
351
351
def __init__ (self , * , name : Optional [str ] = None ) -> None :
352
352
super ().__init__ (name = name )
353
- self ._routes : List [ResourceRoute ] = []
353
+ self ._routes : Dict [str , ResourceRoute ] = {}
354
+ self ._any_route : Optional [ResourceRoute ] = None
355
+ self ._allowed_methods : Set [str ] = set ()
354
356
355
357
def add_route (
356
358
self ,
@@ -359,14 +361,12 @@ def add_route(
359
361
* ,
360
362
expect_handler : Optional [_ExpectHandler ] = None ,
361
363
) -> "ResourceRoute" :
362
-
363
- for route_obj in self ._routes :
364
- if route_obj .method == method or route_obj .method == hdrs .METH_ANY :
365
- raise RuntimeError (
366
- "Added route will never be executed, "
367
- "method {route.method} is already "
368
- "registered" .format (route = route_obj )
369
- )
364
+ if route := self ._routes .get (method , self ._any_route ):
365
+ raise RuntimeError (
366
+ "Added route will never be executed, "
367
+ f"method { route .method } is already "
368
+ "registered"
369
+ )
370
370
371
371
route_obj = ResourceRoute (method , handler , self , expect_handler = expect_handler )
372
372
self .register_route (route_obj )
@@ -376,23 +376,18 @@ def register_route(self, route: "ResourceRoute") -> None:
376
376
assert isinstance (
377
377
route , ResourceRoute
378
378
), f"Instance of Route class is required, got { route !r} "
379
- self ._routes .append (route )
379
+ if route .method == hdrs .METH_ANY :
380
+ self ._any_route = route
381
+ else :
382
+ self ._allowed_methods .add (route .method )
383
+ self ._routes [route .method ] = route
380
384
381
385
async def resolve (self , request : Request ) -> _Resolve :
382
- allowed_methods : Set [str ] = set ()
383
-
384
- match_dict = self ._match (request .rel_url .path_safe )
385
- if match_dict is None :
386
- return None , allowed_methods
387
-
388
- for route_obj in self ._routes :
389
- route_method = route_obj .method
390
- allowed_methods .add (route_method )
391
-
392
- if route_method == request .method or route_method == hdrs .METH_ANY :
393
- return (UrlMappingMatchInfo (match_dict , route_obj ), allowed_methods )
394
- else :
395
- return None , allowed_methods
386
+ if (match_dict := self ._match (request .rel_url .path_safe )) is None :
387
+ return None , set ()
388
+ if route := self ._routes .get (request .method , self ._any_route ):
389
+ return UrlMappingMatchInfo (match_dict , route ), self ._allowed_methods
390
+ return None , self ._allowed_methods
396
391
397
392
@abc .abstractmethod
398
393
def _match (self , path : str ) -> Optional [Dict [str , str ]]:
@@ -402,7 +397,7 @@ def __len__(self) -> int:
402
397
return len (self ._routes )
403
398
404
399
def __iter__ (self ) -> Iterator ["ResourceRoute" ]:
405
- return iter (self ._routes )
400
+ return iter (self ._routes . values () )
406
401
407
402
# TODO: implement all abstract methods
408
403
0 commit comments