Mercurial > p > roundup > code
diff roundup/rest.py @ 5851:167ef847fcdf
issue2551053: Fix routing dict in rest.py
The routing dictionary in rest.py used compiled regular expressions as
dictionary keys. This worked most of the time because the regex lib uses
a cache but resulted in duplicate keys in the dictionary in some cases
where a single key should have been used. Thanks to Robert Klonner for
discovering the problem, debugging the root cause and providing a first
proposed fix.
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Tue, 13 Aug 2019 09:46:02 +0200 |
| parents | 9c6617857032 |
| children | 5e8e160fe2a0 |
line wrap: on
line diff
--- a/roundup/rest.py Sun Aug 04 18:32:57 2019 -0400 +++ b/roundup/rest.py Tue Aug 13 09:46:02 2019 +0200 @@ -291,18 +291,26 @@ # and extract the variable names to a list [(class), (id)] func_vars = cls.__var_to_regex.findall(rule) rule = re.compile(cls.__var_to_regex.sub(cls.url_to_regex, rule)) + # Save pattern to represent regex in route_map dictionary + # The entries consist of a 2-tuple of the (rule, dictionary) + # where rule is the compiled regex and dictionary contains the + # func_obj dict indexed by method. + pattern = rule.pattern # then we decorate it: - # route_map[regex][method] = func + # route_map[pattern] = (rule, func_dict) + # where func_dict is a dictionary of func_obj (see below) + # indexed by method name def decorator(func): - rule_route = cls.__route_map.get(rule, {}) + rule_route = cls.__route_map.get(pattern, (rule, {})) + rule_dict = rule_route [1] func_obj = { 'func': func, 'vars': func_vars } for method in methods: - rule_route[method] = func_obj - cls.__route_map[rule] = rule_route + rule_dict[method] = func_obj + cls.__route_map[pattern] = rule_route return func return decorator @@ -318,11 +326,12 @@ # find the rule match the path # then get handler match the method - for path_regex in cls.__route_map: + for path_regex, funcs in cls.__route_map.values(): + # use compiled regex to find rule match_obj = path_regex.match(path) if match_obj: try: - func_obj = cls.__route_map[path_regex][method] + func_obj = funcs[method] except KeyError: raise Reject('Method %s not allowed' % method)
