Commit a6cfcc00 authored by Shane Hathaway's avatar Shane Hathaway

Fixed a memory leak in TALES. If an exception occurs in a repeat block, a

cycle is left behind that includes a SafeMapping, and SafeMappings are not
aware of GC, therefore the cycle can't be collected.  Iterator is also in the
cycle, however, and it does not need a strong reference to the Context object,
since the Context refers to the Iterator.  So Iterators now refer to Context
through a weak reference.
parent 3a7b1f58
...@@ -15,9 +15,10 @@ ...@@ -15,9 +15,10 @@
An implementation of a generic TALES engine An implementation of a generic TALES engine
""" """
__version__='$Revision: 1.37 $'[11:-2] __version__='$Revision: 1.38 $'[11:-2]
import re, sys, ZTUtils import re, sys, ZTUtils
from weakref import ref
from MultiMapping import MultiMapping from MultiMapping import MultiMapping
from DocumentTemplate.DT_Util import ustr from DocumentTemplate.DT_Util import ustr
from GlobalTranslationService import getGlobalTranslationService from GlobalTranslationService import getGlobalTranslationService
...@@ -63,11 +64,13 @@ class Iterator(ZTUtils.Iterator): ...@@ -63,11 +64,13 @@ class Iterator(ZTUtils.Iterator):
def __init__(self, name, seq, context): def __init__(self, name, seq, context):
ZTUtils.Iterator.__init__(self, seq) ZTUtils.Iterator.__init__(self, seq)
self.name = name self.name = name
self._context = context self._context_ref = ref(context)
def next(self): def next(self):
if ZTUtils.Iterator.next(self): if ZTUtils.Iterator.next(self):
self._context.setLocal(self.name, self.item) context = self._context_ref()
if context is not None:
context.setLocal(self.name, self.item)
return 1 return 1
return 0 return 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment