Index: Lib/test/test_xml_etree.py =================================================================== --- Lib/test/test_xml_etree.py (revision 73515) +++ Lib/test/test_xml_etree.py (working copy) @@ -210,7 +210,18 @@ """ ET.XML("" % encoding) +def check_issue6233(): + """ + >>> from xml.etree import ElementTree as ET + >>> e = ET.XML("t\xe3g") + >>> ET.tostring(e, 'ascii') + b"\\ntãg" + >>> e = ET.XML("t\xe3g".encode('iso-8859-1')) # create byte string with the right encoding + >>> ET.tostring(e, 'ascii') + b"\\ntãg" + """ + # # xinclude tests (samples from appendix C of the xinclude specification) Index: Lib/xml/etree/ElementTree.py =================================================================== --- Lib/xml/etree/ElementTree.py (revision 73515) +++ Lib/xml/etree/ElementTree.py (working copy) @@ -742,11 +742,14 @@ def _encode(s, encoding): if encoding: - return s.encode(encoding) + try: + return s.encode(encoding) + except UnicodeEncodeError as e: + return _escape.sub(_escape_entities, s).encode(encoding) else: return s -_escape = re.compile(r"[&<>\"\u0080-\uffff]+") +_escape = re.compile(r"[&<>\"\x80-\xff]+") _escape_map = { "&": "&", @@ -768,26 +771,20 @@ "cannot serialize %r (type %s)" % (text, type(text).__name__) ) -def _encode_entity(text, pattern=_escape): - # map reserved and non-ascii characters to numerical entities - def escape_entities(m, map=_escape_map): - out = [] - append = out.append - for char in m.group(): - text = map.get(char) - if text is None: - text = "&#%d;" % ord(char) - append(text) - return "".join(out) - try: - return _encode(pattern.sub(escape_entities, text), "ascii") - except TypeError: - _raise_serialization_error(text) - # # the following functions assume an ascii-compatible encoding # (or "utf-16") +def _escape_entities(m, map=_escape_map): + out = [] + append = out.append + for char in m.group(): + text = map.get(char) + if text is None: + text = "&#%d;" % ord(char) + append(text) + return "".join(out) + def _escape_cdata(text): # escape character data try: