Commits

Olemis Lang committed fa0fcf0

ThemeEngine #9580: Skipping nested calls to __init__ using recursion counter

Comments (0)

Files changed (2)

 tho/themeengine/t-9580-tc-infinite-recursion.diff
+tho/themeengine/t-9580-infinite-recursion.diff
 # Placed by Bitbucket

tho/themeengine/t-9580-infinite-recursion.diff

+diff -r 379d6cfc8bf3 trac/core.py
+--- a/trac/core.py	Thu Jan 19 14:14:39 2012 -0500
++++ b/trac/core.py	Fri Jan 20 08:27:53 2012 -0500
+@@ -94,6 +94,24 @@
+     def __new__(mcs, name, bases, d):
+         """Create the component class."""
+ 
++        real_init = d.get('__init__')
++        if real_init:
++            def norec_init(f):
++                """Ignore nested calls to function f"""
++                # Recursion counter stored in wrapper's closure
++                rec_counter = [0]
++                def __init__(self, *args, **kwargs):
++                    # No need to return anything
++                    if rec_counter[0] == 0:
++                        try:
++                            rec_counter[0] += 1
++                            f(self, *args, **kwargs)
++                        finally:
++                            rec_counter[0] -= 1
++                return __init__
++
++            d['__init__'] = norec_init(real_init)
++
+         new_class = type.__new__(mcs, name, bases, d)
+         if name == 'Component':
+             # Don't put the Component base class in the registry