From 90d8ab6c2d9b8252e062b43aaa43e96a8ab65e67 Mon Sep 17 00:00:00 2001 From: Zane Bitter Date: Wed, 14 Sep 2016 18:30:15 -0400 Subject: [PATCH] Avoid circular references in Macro class Just as we store a weakref to the stack in the Function class, we must also do the same with the template in the Macro class. Otherwise we end up with circular references that don't get cleaned up until the garbage collector runs. Change-Id: Ia615de961f52e9fc5ef90e0668720b42c864a605 Closes-Bug: #1623706 --- heat/engine/function.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/heat/engine/function.py b/heat/engine/function.py index f4122158f..8477964fb 100644 --- a/heat/engine/function.py +++ b/heat/engine/function.py @@ -140,9 +140,19 @@ class Macro(Function): def __init__(self, stack, fn_name, raw_args, parse_func, template): """Initialise with the argument syntax tree and parser function.""" super(Macro, self).__init__(stack, fn_name, raw_args) - self.template = template + self._tmplref = weakref.ref(template) if template is not None else None self.parsed = self.parse_args(parse_func) + @property + def template(self): + ref = self._tmplref + if ref is None: + return None + + tmpl = ref() + assert tmpl is not None, "Need a reference to the Template object" + return tmpl + @abc.abstractmethod def parse_args(self, parse_func): """Parse the macro using the supplied parsing function.