From 4c410dd48aefc69682c30f28e830e5dee62a04ab Mon Sep 17 00:00:00 2001 From: Nathan Fritz Date: Thu, 13 May 2010 04:45:36 +0800 Subject: fixed a rather large memory leak --- sleekxmpp/plugins/xep_0045.py | 4 ++-- sleekxmpp/stanza/error.py | 2 +- sleekxmpp/stanza/htmlim.py | 3 ++- sleekxmpp/stanza/nick.py | 3 ++- sleekxmpp/xmlstream/stanzabase.py | 14 +++++++++----- 5 files changed, 16 insertions(+), 10 deletions(-) (limited to 'sleekxmpp') diff --git a/sleekxmpp/plugins/xep_0045.py b/sleekxmpp/plugins/xep_0045.py index 240e6b9a..937c6f96 100644 --- a/sleekxmpp/plugins/xep_0045.py +++ b/sleekxmpp/plugins/xep_0045.py @@ -93,10 +93,10 @@ class MUCPresence(ElementBase): return self def getNick(self): - return self.parent['from'].resource + return self.parent()['from'].resource def getRoom(self): - return self.parent['from'].bare + return self.parent()['from'].bare def setNick(self, value): logging.warning("Cannot set nick through mucpresence plugin.") diff --git a/sleekxmpp/stanza/error.py b/sleekxmpp/stanza/error.py index a1454d1e..15af6624 100644 --- a/sleekxmpp/stanza/error.py +++ b/sleekxmpp/stanza/error.py @@ -22,7 +22,7 @@ class Error(ElementBase): self['type'] = 'cancel' self['condition'] = 'feature-not-implemented' if self.parent is not None: - self.parent['type'] = 'error' + self.parent()['type'] = 'error' def getCondition(self): for child in self.xml.getchildren(): diff --git a/sleekxmpp/stanza/htmlim.py b/sleekxmpp/stanza/htmlim.py index f9ee985f..60686e4a 100644 --- a/sleekxmpp/stanza/htmlim.py +++ b/sleekxmpp/stanza/htmlim.py @@ -31,4 +31,5 @@ class HTMLIM(ElementBase): return html def delHtml(self): - return self.__del__() + if self.parent is not None: + self.parent().xml.remove(self.xml) diff --git a/sleekxmpp/stanza/nick.py b/sleekxmpp/stanza/nick.py index 92a523d6..ac7e3604 100644 --- a/sleekxmpp/stanza/nick.py +++ b/sleekxmpp/stanza/nick.py @@ -22,4 +22,5 @@ class Nick(ElementBase): return self.xml.text def delNick(self): - return self.__del__() + if self.parent is not None: + self.parent().xml.remove(self.xml) diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py index 57c727a3..018e81c3 100644 --- a/sleekxmpp/xmlstream/stanzabase.py +++ b/sleekxmpp/xmlstream/stanzabase.py @@ -9,6 +9,7 @@ from xml.etree import cElementTree as ET import logging import traceback import sys +import weakref if sys.version_info < (3,0): from . import tostring26 as tostring @@ -51,7 +52,10 @@ class ElementBase(tostring.ToString): subitem = None def __init__(self, xml=None, parent=None): - self.parent = parent + if parent is None: + self.parent = None + else: + self.parent = weakref.ref(parent) self.xml = xml self.plugins = {} self.iterables = [] @@ -158,7 +162,7 @@ class ElementBase(tostring.ToString): else: self.xml.append(new) if self.parent is not None: - self.parent.xml.append(self.xml) + self.parent().xml.append(self.xml) return True #had to generate XML else: return False @@ -302,9 +306,9 @@ class ElementBase(tostring.ToString): self.xml.append(xml) return self - def __del__(self): - if self.parent is not None: - self.parent.xml.remove(self.xml) + #def __del__(self): #prevents garbage collection of reference cycle + # if self.parent is not None: + # self.parent.xml.remove(self.xml) class StanzaBase(ElementBase): name = 'stanza' -- cgit v1.2.3 From 7522839141e7dd5bd081a421a58b0962b705fdda Mon Sep 17 00:00:00 2001 From: Nathan Fritz Date: Thu, 13 May 2010 09:07:20 +0800 Subject: added test for unsolicided unavailable presence and fixed bug to make it pass --- sleekxmpp/basexmpp.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'sleekxmpp') diff --git a/sleekxmpp/basexmpp.py b/sleekxmpp/basexmpp.py index fef8538a..13fe2100 100644 --- a/sleekxmpp/basexmpp.py +++ b/sleekxmpp/basexmpp.py @@ -271,12 +271,13 @@ class basexmpp(object): name = self.roster[jid].get('name', '') if show == 'unavailable': logging.debug("%s %s got offline" % (jid, resource)) - if len(self.roster[jid]['presence']): - del self.roster[jid]['presence'][resource] - else: + del self.roster[jid]['presence'][resource] + if len(self.roster[jid]['presence']) == 0 and not self.roster[jid]['in_roster']: del self.roster[jid] if not wasoffline: self.event("got_offline", presence) + else: + return False self.event("changed_status", presence) name = '' if name: -- cgit v1.2.3