Skip to content

Commit 52bf8b7

Browse files
committed
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.
1 parent 3631944 commit 52bf8b7

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

CHANGES.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ Fixed:
152152
install.
153153
- issue2551008: fix incorrect encoding handling in mailgw.py
154154
(Ezio Melotti, John Rouillard)
155+
- issue2551053: the routing dictionary in rest.py used compiled regular
156+
expressions as dictionary keys. This worked most of the time because
157+
the regex lib uses a cache but resulted in duplicate keys in the
158+
dictionary in some cases where a single key should have been used.
159+
Thanks to Robert Klonner for discovering the problem, debugging the
160+
root cause and providing a first proposed fix.
155161

156162
2018-07-13 1.6.0
157163

doc/acknowledgements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ James Kew,
181181
Sheila King,
182182
Michael Klatt,
183183
Bastian Kleineidam,
184+
Robert Klonner,
184185
Axel Kollmorgen,
185186
Cédric Krier,
186187
John Kristensen,

roundup/rest.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,18 +291,26 @@ def index():
291291
# and extract the variable names to a list [(class), (id)]
292292
func_vars = cls.__var_to_regex.findall(rule)
293293
rule = re.compile(cls.__var_to_regex.sub(cls.url_to_regex, rule))
294+
# Save pattern to represent regex in route_map dictionary
295+
# The entries consist of a 2-tuple of the (rule, dictionary)
296+
# where rule is the compiled regex and dictionary contains the
297+
# func_obj dict indexed by method.
298+
pattern = rule.pattern
294299

295300
# then we decorate it:
296-
# route_map[regex][method] = func
301+
# route_map[pattern] = (rule, func_dict)
302+
# where func_dict is a dictionary of func_obj (see below)
303+
# indexed by method name
297304
def decorator(func):
298-
rule_route = cls.__route_map.get(rule, {})
305+
rule_route = cls.__route_map.get(pattern, (rule, {}))
306+
rule_dict = rule_route [1]
299307
func_obj = {
300308
'func': func,
301309
'vars': func_vars
302310
}
303311
for method in methods:
304-
rule_route[method] = func_obj
305-
cls.__route_map[rule] = rule_route
312+
rule_dict[method] = func_obj
313+
cls.__route_map[pattern] = rule_route
306314
return func
307315
return decorator
308316

@@ -318,11 +326,12 @@ def execute(cls, instance, path, method, input):
318326

319327
# find the rule match the path
320328
# then get handler match the method
321-
for path_regex in cls.__route_map:
329+
for path_regex, funcs in cls.__route_map.values():
330+
# use compiled regex to find rule
322331
match_obj = path_regex.match(path)
323332
if match_obj:
324333
try:
325-
func_obj = cls.__route_map[path_regex][method]
334+
func_obj = funcs[method]
326335
except KeyError:
327336
raise Reject('Method %s not allowed' % method)
328337

0 commit comments

Comments
 (0)