Index: Lib/test/test_pyexpat.py
===================================================================
--- Lib/test/test_pyexpat.py (revision 72797)
+++ Lib/test/test_pyexpat.py (working copy)
@@ -130,12 +130,20 @@
'ExternalEntityRefHandler'
]
+ def _hookup_callbacks(self, parser, handler):
+ """
+ Set each of the callbacks defined on handler and named in
+ self.handler_names on the given parser.
+ """
+ for name in self.handler_names:
+ setattr(parser, name, getattr(handler, name))
+
+
def test_utf8(self):
out = self.Outputter()
parser = expat.ParserCreate(namespace_separator='!')
- for name in self.handler_names:
- setattr(parser, name, getattr(out, name))
+ self._hookup_callbacks(parser, out)
parser.returns_unicode = 0
parser.Parse(data, 1)
@@ -164,8 +172,7 @@
out = self.Outputter()
parser = expat.ParserCreate(namespace_separator='!')
parser.returns_unicode = 1
- for name in self.handler_names:
- setattr(parser, name, getattr(out, name))
+ self._hookup_callbacks(parser, out)
parser.Parse(data, 1)
@@ -193,8 +200,7 @@
out = self.Outputter()
parser = expat.ParserCreate(namespace_separator='!')
parser.returns_unicode = 1
- for name in self.handler_names:
- setattr(parser, name, getattr(out, name))
+ self._hookup_callbacks(parser, out)
file = StringIO.StringIO(data)
parser.ParseFile(file)
@@ -219,6 +225,7 @@
self.assertEquals(op[16], "End element: u'root'")
+
class NamespaceSeparatorTest(unittest.TestCase):
def test_legal(self):
# Tests that make sure we get errors when the namespace_separator value
@@ -560,6 +567,48 @@
self.assertEquals(self.n, 4)
+class ForeignDTDTests(unittest.TestCase):
+ """
+ Tests for the UseForeignDTD method of expat parser objects.
+ """
+ def test_use_foreign_dtd(self):
+ """
+ If UseForeignDTD is passed True and a document without an external
+ entity reference is parsed, ExternalEntityRefHandler is first called
+ with None for the public and system ids.
+ """
+ handler_call_args = []
+ def resolve_entity(context, base, system_id, public_id):
+ handler_call_args.append((public_id, system_id))
+ return 1
+
+ parser = expat.ParserCreate()
+ parser.UseForeignDTD(True)
+ parser.SetParamEntityParsing(expat.XML_PARAM_ENTITY_PARSING_ALWAYS)
+ parser.ExternalEntityRefHandler = resolve_entity
+ parser.Parse("")
+ self.assertEquals(handler_call_args, [(None, None)])
+
+ def test_ignore_use_foreign_dtd(self):
+ """
+ If UseForeignDTD is passed True and a document with an external
+ entity reference is parsed, ExternalEntityRefHandler is called with
+ the public and system ids from the document.
+ """
+ handler_call_args = []
+ def resolve_entity(context, base, system_id, public_id):
+ handler_call_args.append((public_id, system_id))
+ return 1
+
+ parser = expat.ParserCreate()
+ parser.UseForeignDTD(True)
+ parser.SetParamEntityParsing(expat.XML_PARAM_ENTITY_PARSING_ALWAYS)
+ parser.ExternalEntityRefHandler = resolve_entity
+ parser.Parse(
+ "")
+ self.assertEquals(handler_call_args, [("bar", "baz")])
+
+
def test_main():
run_unittest(SetAttributeTest,
ParseTest,
@@ -569,7 +618,8 @@
HandlerExceptionTest,
PositionTest,
sf1296433Test,
- ChardataBufferTest)
+ ChardataBufferTest,
+ ForeignDTDTests)
if __name__ == "__main__":
test_main()
Index: Doc/library/pyexpat.rst
===================================================================
--- Doc/library/pyexpat.rst (revision 72797)
+++ Doc/library/pyexpat.rst (working copy)
@@ -157,7 +157,14 @@
:attr:`ordered_attributes`, :attr:`returns_unicode` and
:attr:`specified_attributes` set to the values of this parser.
+.. method:: xmlparser.SetParamEntityParsing(flag)
+ Controls parsing of parameter entities (including the external DTD subset).
+ Possible *flag* values are :const:`XML_PARAM_ENTITY_PARSING_NEVER`,
+ :const:`XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE` and
+ :const:`XML_PARAM_ENTITY_PARSING_ALWAYS`. Returns true if setting the flag
+ was successful.
+
.. method:: xmlparser.UseForeignDTD([flag])
Calling this with a true value for *flag* (the default) will cause Expat to call