diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py
index 3044960a0ed165..741ff928311364 100644
--- a/Lib/test/test_sax.py
+++ b/Lib/test/test_sax.py
@@ -13,7 +13,8 @@
from xml.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \
XMLFilterBase, prepare_input_source
from xml.sax.expatreader import create_parser
-from xml.sax.handler import feature_namespaces, feature_external_ges
+from xml.sax.handler import feature_namespaces, feature_external_ges,\
+ property_xml_string
from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl
from io import BytesIO, StringIO
import codecs
@@ -1311,6 +1312,73 @@ def test_nsattrs_wattr(self):
self.assertEqual(attrs.getQNameByName((ns_uri, "attr")), "ns:attr")
+# ===========================================================================
+#
+# Sax parser property tests
+#
+# Currently only tests the condition reported in issue bpo-6686
+#
+# ===========================================================================
+
+class PropertyContentHandler(ContentHandler):
+ def __init__(self, test_harness, reader, test, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.test_harness = test_harness
+ self.reader = reader
+ self.test_data = test
+
+ def startElement(self, name, attr):
+ property_ = self.reader.getProperty(property_xml_string)
+ self.test_harness.assertIsInstance(property_, bytes)
+ if self.test_harness.test_data is not None:
+ prop = property_
+ self.test_harness\
+ .assertEqual(prop.decode(encoding=self.test_data[0]),
+ self.test_data[1][1])
+ super().startElement(name, attr)
+
+
+class SaxPropertyTest(unittest.TestCase):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.result = None
+ self.test_data = [['ascii', ['Hello']],
+ ['utf-8', ['abc˦']],
+ ['iso-8859-1', ['ghiéñ']]]
+ for t in self.test_data:
+ d = '{}\n'.format(t[1][0])
+ t[1].append(d)
+
+ def test_property_xml_string_from_bytes(self):
+ for prolog in (True, False):
+ for t in self.test_data:
+ reader = create_parser()
+ reader.setContentHandler(PropertyContentHandler(self,
+ reader,
+ t))
+ source = InputSource()
+ data = b''
+ if prolog:
+ data += b'\n'
+ data += t[1][1].encode(t[0])
+ source.setByteStream(BytesIO(data))
+ if not prolog:
+ source.setEncoding(t[0])
+ reader.parse(source)
+ pass
+
+ def test_property_xml_str_from_str(self):
+ self.test_data = None
+ reader = create_parser()
+ reader.setContentHandler(PropertyContentHandler(self,
+ reader,
+ None))
+ in_ = '\nHi there'
+ reader.parse(StringIO(in_))
+
+
def test_main():
run_unittest(MakeParserTest,
ParseTest,
@@ -1323,7 +1391,9 @@ def test_main():
StreamReaderWriterXmlgenTest,
ExpatReaderTest,
ErrorReportingTest,
- XmlReaderTest)
+ XmlReaderTest,
+ SaxPropertyTest)
+
if __name__ == "__main__":
test_main()
diff --git a/Lib/xml/sax/expatreader.py b/Lib/xml/sax/expatreader.py
index 5066ffc2fa51f0..48abf5d1d9528e 100644
--- a/Lib/xml/sax/expatreader.py
+++ b/Lib/xml/sax/expatreader.py
@@ -3,8 +3,6 @@
pyexpat.__version__ == '2.22'.
"""
-version = "0.20"
-
from xml.sax._exceptions import *
from xml.sax.handler import feature_validation, feature_namespaces
from xml.sax.handler import feature_namespace_prefixes
@@ -27,6 +25,8 @@
raise SAXReaderNotAvailable("expat not supported", None)
from xml.sax import xmlreader, saxutils, handler
+version = "0.20"
+
AttributesImpl = xmlreader.AttributesImpl
AttributesNSImpl = xmlreader.AttributesNSImpl
@@ -266,12 +266,14 @@ def _reset_lex_handler_prop(self):
parser.EndCdataSectionHandler = None
parser.StartDoctypeDeclHandler = None
parser.EndDoctypeDeclHandler = None
+ parser.XmlDeclHandler = None
else:
parser.CommentHandler = lex.comment
parser.StartCdataSectionHandler = lex.startCDATA
parser.EndCdataSectionHandler = lex.endCDATA
parser.StartDoctypeDeclHandler = self.start_doctype_decl
parser.EndDoctypeDeclHandler = lex.endDTD
+ parser.XmlDeclHandler = lex.xml_decl_handler
def reset(self):
if self._namespaces:
diff --git a/Misc/ACKS b/Misc/ACKS
index 5014584b7bc0b7..28673b82bd210a 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -572,6 +572,7 @@ Chris Gonnerman
Shelley Gooch
David Goodger
Elliot Gorokhovsky
+Jonathan Gossage
Hans de Graaff
Tim Graham
Kim Gräsman