mirror of
https://github.com/kennethreitz/responder.git
synced 2026-06-05 23:00:17 +00:00
Merge branch 'master' of github.com:kennethreitz/responder
This commit is contained in:
+11
-13
@@ -1,17 +1,8 @@
|
||||
import re
|
||||
import functools
|
||||
from parse import parse
|
||||
|
||||
|
||||
def memoize(f):
|
||||
def helper(self, s):
|
||||
memoize_key = f"{f.__name__}:{s}"
|
||||
if memoize_key not in self._memo:
|
||||
self._memo[memoize_key] = f(self, s)
|
||||
return self._memo[memoize_key]
|
||||
|
||||
return helper
|
||||
|
||||
|
||||
class Route:
|
||||
_param_pattern = re.compile(r"{([^{}]*)}")
|
||||
|
||||
@@ -20,7 +11,6 @@ class Route:
|
||||
self.endpoint = endpoint
|
||||
self.uses_websocket = websocket
|
||||
self.before_request = before_request
|
||||
self._memo = {}
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Route {self.route!r}={self.endpoint!r}>"
|
||||
@@ -45,7 +35,7 @@ class Route:
|
||||
def has_parameters(self):
|
||||
return bool(self._param_pattern.search(self.route))
|
||||
|
||||
@memoize
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def does_match(self, s):
|
||||
if s == self.route:
|
||||
return True
|
||||
@@ -53,7 +43,7 @@ class Route:
|
||||
named = self.incoming_matches(s)
|
||||
return bool(len(named))
|
||||
|
||||
@memoize
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def incoming_matches(self, s):
|
||||
results = parse(self.route, s)
|
||||
return results.named if results else {}
|
||||
@@ -75,3 +65,11 @@ class Route:
|
||||
code = hasattr(self.endpoint, "__code__")
|
||||
kwdefaults = hasattr(self.endpoint, "__kwdefaults__")
|
||||
return all((callable(self.endpoint), code, kwdefaults))
|
||||
|
||||
def __hash__(self):
|
||||
return (
|
||||
hash(self.route)
|
||||
^ hash(self.endpoint)
|
||||
^ hash(self.uses_websocket)
|
||||
^ hash(self.before_request)
|
||||
)
|
||||
|
||||
+12
-11
@@ -2,6 +2,10 @@ import pytest
|
||||
from responder import routes
|
||||
|
||||
|
||||
def setup_function(function):
|
||||
routes.Route.incoming_matches.cache_clear()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"route, expected",
|
||||
[
|
||||
@@ -36,26 +40,23 @@ def test_incoming_matches():
|
||||
assert r.incoming_matches("/hello") == {"greetings": "hello"}
|
||||
assert r.incoming_matches("/foo") == {"greetings": "foo"}
|
||||
|
||||
assert r._memo == {
|
||||
"incoming_matches:/hello": {"greetings": "hello"},
|
||||
"incoming_matches:/foo": {"greetings": "foo"},
|
||||
}
|
||||
|
||||
# Test Route with two params
|
||||
r = routes.Route("/{greetings}/{name}", "test_endpoint")
|
||||
assert r.incoming_matches("/hi/john") == {"greetings": "hi", "name": "john"}
|
||||
assert r.incoming_matches("/hello/jane") == {"greetings": "hello", "name": "jane"}
|
||||
|
||||
# Test Route with no param
|
||||
assert r._memo == {
|
||||
"incoming_matches:/hi/john": {"greetings": "hi", "name": "john"},
|
||||
"incoming_matches:/hello/jane": {"greetings": "hello", "name": "jane"},
|
||||
}
|
||||
|
||||
r = routes.Route("/hello", "test_endpoint")
|
||||
assert r.incoming_matches("/hello") == {}
|
||||
assert r.incoming_matches("/bye") == {}
|
||||
assert r._memo == {"incoming_matches:/hello": {}, "incoming_matches:/bye": {}}
|
||||
|
||||
|
||||
def test_incoming_matches_cache():
|
||||
r = routes.Route("/hello", "test_endpoint")
|
||||
r.incoming_matches("/hello")
|
||||
assert r.incoming_matches.cache_info().hits == 0
|
||||
r.incoming_matches("/hello")
|
||||
assert r.incoming_matches.cache_info().hits == 1
|
||||
|
||||
|
||||
def test_incoming_matches_with_concrete_path_no_match():
|
||||
|
||||
Reference in New Issue
Block a user