summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFred Drake <fdrake@acm.org>2002-04-04 17:57:08 (GMT)
committerFred Drake <fdrake@acm.org>2002-04-04 17:57:08 (GMT)
commit012c81fc9720c8504da73b26f503b0ef8640da19 (patch)
tree7a4a8a535e36470ebc0cbc5e01685d01ad58302e
parent2e1c09c1fd06531a3ce1de5b12ec5c8f771e78e0 (diff)
downloadcpython-012c81fc9720c8504da73b26f503b0ef8640da19.zip
cpython-012c81fc9720c8504da73b26f503b0ef8640da19.tar.gz
cpython-012c81fc9720c8504da73b26f503b0ef8640da19.tar.bz2
Avoid creating circular references between the ExpatParser and the
ContentHandler. While GC will eventually clean up, it can take longer than normal for applications that create a lot of strings (or other immutables) rather without creating many containers. This closes SF bug #535474.
-rw-r--r--Lib/xml/sax/expatreader.py39
1 files changed, 38 insertions, 1 deletions
diff --git a/Lib/xml/sax/expatreader.py b/Lib/xml/sax/expatreader.py
index 5473b36..2732ab0 100644
--- a/Lib/xml/sax/expatreader.py
+++ b/Lib/xml/sax/expatreader.py
@@ -26,6 +26,43 @@ AttributesImpl = xmlreader.AttributesImpl
AttributesNSImpl = xmlreader.AttributesNSImpl
import string
+import weakref
+
+# --- ExpatLocator
+
+class ExpatLocator(xmlreader.Locator):
+ """Locator for use with the ExpatParser class.
+
+ This uses a weak reference to the parser object to avoid creating
+ a circular reference between the parser and the content handler.
+ """
+ def __init__(self, parser):
+ self._ref = weakref.ref(parser)
+
+ def getColumnNumber(self):
+ parser = self._ref()
+ if parser is None or parser._parser is None:
+ return None
+ return parser._parser.ErrorColumnNumber
+
+ def getLineNumber(self):
+ parser = self._ref()
+ if parser is None or parser._parser is None:
+ return 1
+ return self._parser.ErrorLineNumber
+
+ def getPublicId(self):
+ parser = self._ref()
+ if parser is None:
+ return None
+ return parser._source.getPublicId()
+
+ def getSystemId(self):
+ parser = self._ref()
+ if parser is None:
+ return None
+ return parser._source.getSystemId()
+
# --- ExpatParser
@@ -49,7 +86,7 @@ class ExpatParser(xmlreader.IncrementalParser, xmlreader.Locator):
self._source = source
self.reset()
- self._cont_handler.setDocumentLocator(self)
+ self._cont_handler.setDocumentLocator(ExpatLocator(self))
xmlreader.IncrementalParser.parse(self, source)
def prepareParser(self, source):