Printing of XML and UUID boxes with non-ascii characters only fully supported in 3.x

In 2.x, the XML contents will be printed as entity references instead.
It's just too difficult to get both 2.x and 3.x to be entirely consistent,
and so 3.x gets the preferential treatment.  Closes #131.
This commit is contained in:
John Evans 2013-10-13 11:40:54 -04:00
commit ff97e0fb82
3 changed files with 71 additions and 48 deletions

View file

@ -2747,9 +2747,18 @@ def _pretty_print_xml(xml, level=0):
"""
xml = copy.deepcopy(xml)
_indent(xml.getroot(), level=level)
xmltext = ET.tostring(xml.getroot()).decode('utf-8')
xmltext = ET.tostring(xml.getroot(), encoding='utf-8').decode('utf-8')
# Indent it a bit.
lst = [(' ' + x) for x in xmltext.split('\n')]
xml = '\n'.join(lst)
return '\n{0}'.format(xml)
try:
xml = '\n'.join(lst)
return '\n{0}'.format(xml)
except UnicodeEncodeError:
# This can happen on python 2.x if the character set contains certain
# non-ascii characters. Just print out the corresponding xml char
# entities instead.
xml = u'\n'.join(lst)
text = u'\n{0}'.format(xml)
text = text.encode('ascii', 'xmlcharrefreplace')
return text

View file

@ -148,54 +148,26 @@ class TestXML(unittest.TestCase):
self.assertEqual(neighbor.attrib['name'], 'Malaysia')
self.assertEqual(neighbor.attrib['direction'], 'N')
@unittest.skipIf(os.name == "nt", "Temporary file issue on window.")
class TestUTF8XML(unittest.TestCase):
"""Test suite for UTF-8 XML boxes."""
def setUp(self):
"""Create a JP2 file with a UTF-8 XML box."""
self.j2kfile = glymur.data.goodstuff()
# 'Россия' is 'Russia' in Cyrillic, not that it matters.
xml = u"""<?xml version="1.0" encoding="utf-8"?>
<country>Россия</country>"""
with tempfile.NamedTemporaryFile(suffix=".xml", delete=False) as tfile:
tfile.write(xml.encode('utf-8'))
tfile.flush()
self.xmlfile = tfile.name
j2k = glymur.Jp2k(self.j2kfile)
with tempfile.NamedTemporaryFile(suffix=".jp2", delete=False) as tfile:
jp2 = j2k.wrap(tfile.name)
xmlbox = glymur.jp2box.XMLBox(filename=self.xmlfile)
jp2.append(xmlbox)
self.jp2_xml_file = tfile.name
def tearDown(self):
os.unlink(self.xmlfile)
os.unlink(self.jp2_xml_file)
def test_utf8_xml(self):
"""Should be able to write/read an XMLBox with utf-8 encoding."""
jp2 = Jp2k(self.jp2_xml_file)
box_xml = jp2.box[-1].xml.getroot()
box_xml_str = ET.tostring(box_xml, encoding='utf-8').decode('utf-8')
self.assertEqual(box_xml_str,
u'<country>Россия</country>')
# 'Россия' is 'Russia' in Cyrillic, not that it matters.
xml = u"""<?xml version="1.0" encoding="utf-8"?>
<country>Россия</country>"""
with tempfile.NamedTemporaryFile(suffix=".xml") as xmlfile:
xmlfile.write(xml.encode('utf-8'))
xmlfile.flush()
@unittest.skip("Does not print properly.")
def test_printing_utf8_xml(self):
"""Should be able to print an XMLBox with utf-8 encoding."""
jp2 = Jp2k(self.jp2_xml_file)
with patch('sys.stdout', new=StringIO()) as fake_out:
print(jp2.box[-1])
actual = fake_out.getvalue().strip()
lines = ["XML Box (xml ) @ (115305, 39)",
" u'<country>Россия</country>'"]
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
j2k = glymur.Jp2k(self.j2kfile)
with tempfile.NamedTemporaryFile(suffix=".jp2") as jfile:
jp2 = j2k.wrap(jfile.name)
xmlbox = glymur.jp2box.XMLBox(filename=xmlfile.name)
jp2.append(xmlbox)
box_xml = jp2.box[-1].xml.getroot()
box_xml_str = ET.tostring(box_xml,
encoding='utf-8').decode('utf-8')
self.assertEqual(box_xml_str,
u'<country>Россия</country>')

View file

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
"""Test suite for printing.
"""
# C0302: don't care too much about having too many lines in a test module
@ -15,6 +16,7 @@ import struct
import sys
import tempfile
import warnings
from xml.etree import cElementTree as ET
if sys.hexversion < 0x02070000:
import unittest2 as unittest
@ -730,6 +732,46 @@ class TestPrinting(unittest.TestCase):
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
@unittest.skipIf(sys.hexversion < 0x02070000,
"Differences in XML printing between 2.6 and 2.7")
def test_xml_latin1(self):
"""Should be able to print an XMLBox with utf-8 encoding (latin1)."""
text = u"""<?xml version="1.0" encoding="utf-8"?>
<flow>Strömung</flow>"""
if sys.hexversion < 0x03000000:
xml = ET.parse(StringIO(text.encode('utf-8')))
else:
xml = ET.parse(StringIO(text))
xmlbox = glymur.jp2box.XMLBox(xml=xml)
with patch('sys.stdout', new=StringIO()) as fake_out:
print(xmlbox)
actual = fake_out.getvalue().strip()
lines = ["XML Box (xml ) @ (-1, 0)",
" <flow>Strömung</flow>"]
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
@unittest.skipIf(sys.hexversion < 0x02070000,
"Differences in XML printing between 2.6 and 2.7")
def test_xml_cyrrilic(self):
"""Should be able to print an XMLBox with utf-8 encoding (cyrrillic)."""
text = u"""<?xml version="1.0" encoding="utf-8"?>
<country>Россия</country>"""
if sys.hexversion < 0x03000000:
xml = ET.parse(StringIO(text.encode('utf-8')))
else:
xml = ET.parse(StringIO(text))
xmlbox = glymur.jp2box.XMLBox(xml=xml)
with patch('sys.stdout', new=StringIO()) as fake_out:
print(xmlbox)
actual = fake_out.getvalue().strip()
lines = ["XML Box (xml ) @ (-1, 0)",
" <country>Россия</country>"]
expected = '\n'.join(lines)
self.assertEqual(actual, expected)
@unittest.skipIf(OPJ_DATA_ROOT is None,
"OPJ_DATA_ROOT environment variable not set")
def test_channel_definition(self):