Issue #16012: Fix a regression in pyexpat. The parser's UseForeignDTD()
method doesn't require an argument again.
diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py
index 75b031a..b911a20 100644
--- a/Lib/test/test_pyexpat.py
+++ b/Lib/test/test_pyexpat.py
@@ -588,6 +588,58 @@
except expat.ExpatError as e:
self.assertEqual(str(e), 'XML declaration not well-formed: line 1, column 14')
+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("<?xml version='1.0'?><element/>")
+ self.assertEqual(handler_call_args, [(None, None)])
+
+ # test UseForeignDTD() is equal to UseForeignDTD(True)
+ handler_call_args[:] = []
+
+ parser = expat.ParserCreate()
+ parser.UseForeignDTD()
+ parser.SetParamEntityParsing(expat.XML_PARAM_ENTITY_PARSING_ALWAYS)
+ parser.ExternalEntityRefHandler = resolve_entity
+ parser.Parse("<?xml version='1.0'?><element/>")
+ self.assertEqual(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(
+ "<?xml version='1.0'?><!DOCTYPE foo PUBLIC 'bar' 'baz'><element/>")
+ self.assertEqual(handler_call_args, [("bar", "baz")])
+
+
def test_main():
run_unittest(SetAttributeTest,
ParseTest,
@@ -598,7 +650,8 @@
PositionTest,
sf1296433Test,
ChardataBufferTest,
- MalformedInputText)
+ MalformedInputText,
+ ForeignDTDTests)
if __name__ == "__main__":
test_main()
diff --git a/Misc/NEWS b/Misc/NEWS
index 84d4bd1..bbdd5e5 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -379,6 +379,12 @@
- Issue #6884: Fix long-standing bugs with MANIFEST.in parsing in distutils
on Windows.
+Extension Modules
+-----------------
+
+- Issue #16012: Fix a regression in pyexpat. The parser's UseForeignDTD()
+ method doesn't require an argument again.
+
Tests
-----
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index 4d9a1e5..f269113 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -1176,7 +1176,7 @@
PyObject *flagobj = NULL;
int flag = 1;
enum XML_Error rc;
- if (!PyArg_ParseTuple(args, "O:UseForeignDTD", &flagobj))
+ if (!PyArg_ParseTuple(args, "|O:UseForeignDTD", &flagobj))
return NULL;
if (flagobj != NULL) {
flag = PyObject_IsTrue(flagobj);