Detecting Infinite Recursion
I'm creating a macro for Trac, and one of the things it does is to render a bit of wiki text, that can in turn use the same macro. This can give rise to an infinite recursion if th
Solution 1:
Catching the recursion exception is the better approach, but you could also add a decorator on the functions you wanted to 'protect':
from functools import wraps
from threading import local
defrecursion_detector(func):
func._thread_locals = local()
@wraps(func)defwrapper(*args, **kwargs):
params = tuple(args) + tuple(kwargs.items())
ifnothasattr(func._thread_locals, 'seen'):
func._thread_locals.seen = set()
if params in func._thread_locals.seen:
raise RuntimeError('Already called this function with the same arguments')
func._thread_locals.seen.add(params)
try:
res = func(*args, **kwargs)
finally:
func._thread_locals.seen.remove(params)
return res
return wrapper
then apply that decorator to the macro render function.
A simple demo:
>>>@recursion_detector
... def foo(bar):
... return foo(not bar)
...
>>> foo(True)
Traceback (most recent calllast):
File "<stdin>", line 1, in<module>
File "<stdin>", line 10, in wrapper
File "<stdin>", line 3, in foo
File "<stdin>", line 10, in wrapper
File "<stdin>", line 3, in foo
File "<stdin>", line 7, in wrapper
RuntimeError: Already called this functionwith the same arguments
>>> foo(False)
Traceback (most recent calllast):
File "<stdin>", line 1, in<module>
File "<stdin>", line 10, in wrapper
File "<stdin>", line 3, in foo
File "<stdin>", line 10, in wrapper
File "<stdin>", line 3, in foo
File "<stdin>", line 7, in wrapper
RuntimeError: Already called this functionwith the same arguments
Solution 2:
It's easier to just catch the recursion error when it happens, than trying to catch it before it happens, in runtime.
If that's not an option, analyzing the template before rendering could be a way forward as well.
Solution 3:
Equally simple would be to pass dictionary to keep track of used arguments and at the beginning check if argument has already been tried.
Post a Comment for "Detecting Infinite Recursion"