From e4c6feb99b7928bcaace82b8ff21e7863e86cf50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 29 Sep 2010 11:30:06 +0200 Subject: [PATCH] Fix memory leak due to loop references --- tryton/gui/window/form.py | 8 +++----- tryton/gui/window/view_form/model/field.py | 3 +++ tryton/gui/window/view_form/model/group.py | 14 ++++++++++++++ tryton/gui/window/view_form/model/record.py | 8 ++++++++ tryton/gui/window/view_form/screen/screen.py | 9 +++++++-- tryton/gui/window/view_form/view/list.py | 8 ++++---- tryton/gui/window/view_tree/view_tree.py | 1 - tryton/signal_event.py | 3 +++ 8 files changed, 42 insertions(+), 12 deletions(-) diff --git a/tryton/gui/window/form.py b/tryton/gui/window/form.py index d7e68f9401..8024d36ffb 100644 --- a/tryton/gui/window/form.py +++ b/tryton/gui/window/form.py @@ -5,7 +5,6 @@ import gettext import gtk import gobject import locale -import gc import tryton.rpc as rpc from tryton.gui.window.view_form.screen import Screen from tryton.action import Action @@ -200,11 +199,10 @@ class Form(SignalEvent): def destroy(self): self.screen.signal_unconnect(self) self.screen.destroy() - del self.screen - del self.widget + self.screen = None + self.widget = None self.scrolledwindow.destroy() - del self.scrolledwindow - gc.collect() + self.scrolledwindow = None def sel_ids_get(self): return self.screen.sel_ids_get() diff --git a/tryton/gui/window/view_form/model/field.py b/tryton/gui/window/view_form/model/field.py index a32aab80d5..d675456312 100644 --- a/tryton/gui/window/view_form/model/field.py +++ b/tryton/gui/window/view_form/model/field.py @@ -134,6 +134,9 @@ class CharField(object): def get_timestamp(self, record): return {} + def destroy(self): + self.parent = None + class SelectionField(CharField): diff --git a/tryton/gui/window/view_form/model/group.py b/tryton/gui/window/view_form/model/group.py index f4f706d9e9..77ffd8da9c 100644 --- a/tryton/gui/window/view_form/model/group.py +++ b/tryton/gui/window/view_form/model/group.py @@ -334,3 +334,17 @@ class Group(SignalEvent, list): record = self.__id2record[old_id] self.__id2record[record.id] = record del self.__id2record[old_id] + + def destroy(self): + super(Group, self).destroy() + self.__window = None + self.parent = None + for field in self.fields.itervalues(): + field.destroy() + self.fields = None + self.record_removed = None + self.record_deleted = None + self.__id2record = None + for record in self: + record.destroy() + self[:] = [] diff --git a/tryton/gui/window/view_form/model/record.py b/tryton/gui/window/view_form/model/record.py index 982d2f3f81..8ae3ead0b3 100644 --- a/tryton/gui/window/view_form/model/record.py +++ b/tryton/gui/window/view_form/model/record.py @@ -460,3 +460,11 @@ class Record(SignalEvent): except Exception: return 0 return self.attachment_count + + def destroy(self): + super(Record, self).destroy() + self.window = None + self.parent = None + self.group = None + self.value = None + self.next = None diff --git a/tryton/gui/window/view_form/screen/screen.py b/tryton/gui/window/view_form/screen/screen.py index 85a6a27035..570f9feeea 100644 --- a/tryton/gui/window/view_form/screen/screen.py +++ b/tryton/gui/window/view_form/screen/screen.py @@ -239,9 +239,14 @@ class Screen(SignalEvent): def destroy(self): for view in self.views: view.destroy() - del view self.group.signal_unconnect(self) - del self.views + self.group.destroy() + self.parent = None + self.__window = None + self.__group = None + self.__current_record = None + self.screen_container = None + self.widget = None def switch_view(self, view_type=None, default=True, context=None): self.current_view.set_value() diff --git a/tryton/gui/window/view_form/view/list.py b/tryton/gui/window/view_form/view/list.py index 653b1780d5..dd75a7e386 100644 --- a/tryton/gui/window/view_form/view/list.py +++ b/tryton/gui/window/view_form/view/list.py @@ -490,7 +490,7 @@ class ViewList(ParserView): pass def __str__(self): - return 'ViewList (%s)' % self.screen.model_name + return 'ViewList (%d)' % id(self) def __getitem__(self, name): return None @@ -518,9 +518,9 @@ class ViewList(ParserView): except Exception: pass self.widget_tree.destroy() - del self.screen - del self.widget_tree - del self.widget + self.screen = None + self.widget_tree = None + self.widget = None def __sig_switch(self, treeview, path, column): if column._type == 'button': diff --git a/tryton/gui/window/view_tree/view_tree.py b/tryton/gui/window/view_tree/view_tree.py index 4fc5920777..fd7d31744c 100644 --- a/tryton/gui/window/view_tree/view_tree.py +++ b/tryton/gui/window/view_tree/view_tree.py @@ -381,7 +381,6 @@ class ViewTree(object): return True def reload(self): - del self.model self.model = ViewTreeModel(self.ids, self.view_info, self.fields_order, self.fields, self.fields_attrs, context=self.context, pixbufs=self.pixbufs, treeview=self.view) diff --git a/tryton/signal_event.py b/tryton/signal_event.py index 86dd9eadd6..aeff3eb04c 100644 --- a/tryton/signal_event.py +++ b/tryton/signal_event.py @@ -36,3 +36,6 @@ class SignalEvent(object): else: i += 1 return True + + def destroy(self): + self.__connects = None