Package lxml :: Package tests :: Module test_io
[hide private]
[frames] | no frames]

Source Code for Module lxml.tests.test_io

  1  # -*- coding: utf-8 -*- 
  2   
  3  """ 
  4  IO test cases that apply to both etree and ElementTree 
  5  """ 
  6   
  7  import unittest 
  8  import tempfile, gzip, os, os.path, sys, gc, shutil 
  9   
 10  this_dir = os.path.dirname(__file__) 
 11  if this_dir not in sys.path: 
 12      sys.path.insert(0, this_dir) # needed for Py3 
 13   
 14  from common_imports import etree, ElementTree, fileInTestDir, _str, _bytes 
 15  from common_imports import SillyFileLike, LargeFileLike, HelperTestCase 
 16   
17 -class IOTestCaseBase(HelperTestCase):
18 """(c)ElementTree compatibility for IO functions/methods 19 """ 20 etree = None 21
22 - def setUp(self):
23 """Setting up a minimal tree 24 """ 25 self.root = self.etree.Element('a') 26 self.root_str = self.etree.tostring(self.root) 27 self.tree = self.etree.ElementTree(self.root) 28 self._temp_dir = tempfile.mkdtemp()
29
30 - def tearDown(self):
31 gc.collect() 32 shutil.rmtree(self._temp_dir)
33
34 - def getTestFilePath(self, name):
35 return os.path.join(self._temp_dir, name)
36
37 - def buildNodes(self, element, children, depth):
38 Element = self.etree.Element 39 40 if depth == 0: 41 return 42 for i in range(children): 43 new_element = Element('element_%s_%s' % (depth, i)) 44 self.buildNodes(new_element, children, depth - 1) 45 element.append(new_element)
46
47 - def test_tree_io(self):
48 Element = self.etree.Element 49 ElementTree = self.etree.ElementTree 50 51 element = Element('top') 52 element.text = _str("qwrtioüöä\uAABB") 53 tree = ElementTree(element) 54 self.buildNodes(element, 10, 3) 55 f = open(self.getTestFilePath('testdump.xml'), 'wb') 56 tree.write(f, encoding='UTF-8') 57 f.close() 58 f = open(self.getTestFilePath('testdump.xml'), 'rb') 59 tree = ElementTree(file=f) 60 f.close() 61 f = open(self.getTestFilePath('testdump2.xml'), 'wb') 62 tree.write(f, encoding='UTF-8') 63 f.close() 64 f = open(self.getTestFilePath('testdump.xml'), 'rb') 65 data1 = f.read() 66 f.close() 67 f = open(self.getTestFilePath('testdump2.xml'), 'rb') 68 data2 = f.read() 69 f.close() 70 self.assertEquals(data1, data2)
71
72 - def test_tree_io_latin1(self):
73 Element = self.etree.Element 74 ElementTree = self.etree.ElementTree 75 76 element = Element('top') 77 element.text = _str("qwrtioüöäßá") 78 tree = ElementTree(element) 79 self.buildNodes(element, 10, 3) 80 f = open(self.getTestFilePath('testdump.xml'), 'wb') 81 tree.write(f, encoding='iso-8859-1') 82 f.close() 83 f = open(self.getTestFilePath('testdump.xml'), 'rb') 84 tree = ElementTree(file=f) 85 f.close() 86 f = open(self.getTestFilePath('testdump2.xml'), 'wb') 87 tree.write(f, encoding='iso-8859-1') 88 f.close() 89 f = open(self.getTestFilePath('testdump.xml'), 'rb') 90 data1 = f.read() 91 f.close() 92 f = open(self.getTestFilePath('testdump2.xml'), 'rb') 93 data2 = f.read() 94 f.close() 95 self.assertEquals(data1, data2)
96
97 - def test_write_filename(self):
98 # (c)ElementTree supports filename strings as write argument 99 100 handle, filename = tempfile.mkstemp(suffix=".xml") 101 self.tree.write(filename) 102 try: 103 self.assertEqual(open(filename, 'rb').read().replace(_bytes('\n'), _bytes('')), 104 self.root_str) 105 finally: 106 os.close(handle) 107 os.remove(filename)
108
110 filename = os.path.join( 111 os.path.join('hopefullynonexistingpathname'), 112 'invalid_file.xml') 113 try: 114 self.tree.write(filename) 115 except IOError: 116 pass 117 else: 118 self.assertTrue( 119 False, "writing to an invalid file path should fail")
120
122 # (c)ElementTree supports gzip instance as parse argument 123 handle, filename = tempfile.mkstemp(suffix=".xml.gz") 124 f = gzip.open(filename, 'wb') 125 f.write(self.root_str) 126 f.close() 127 try: 128 f_gz = gzip.open(filename, 'rb') 129 tree = self.etree.parse(f_gz) 130 f_gz.close() 131 self.assertEqual(self.etree.tostring(tree.getroot()), self.root_str) 132 finally: 133 os.close(handle) 134 os.remove(filename)
135
137 # (c)ElementTree class ElementTree has a 'parse' method that returns 138 # the root of the tree 139 140 # parse from filename 141 142 handle, filename = tempfile.mkstemp(suffix=".xml") 143 open(filename, 'wb').write(self.root_str) 144 try: 145 tree = self.etree.ElementTree() 146 root = tree.parse(filename) 147 self.assertEqual(self.etree.tostring(root), self.root_str) 148 finally: 149 os.close(handle) 150 os.remove(filename)
151
153 handle, filename = tempfile.mkstemp(suffix=".xml") 154 open(filename, 'wb').write(self.root_str) 155 try: 156 tree = self.etree.ElementTree() 157 root = tree.parse(filename) 158 # and now do it again; previous content should still be there 159 root2 = tree.parse(filename) 160 self.assertEquals('a', root.tag) 161 self.assertEquals('a', root2.tag) 162 # now remove all references to root2, and parse again 163 del root2 164 root3 = tree.parse(filename) 165 self.assertEquals('a', root.tag) 166 self.assertEquals('a', root3.tag) 167 # root2's memory should've been freed here 168 # XXX how to check? 169 finally: 170 os.close(handle) 171 os.remove(filename)
172
174 # (c)ElementTree class ElementTree has a 'parse' method that returns 175 # the root of the tree 176 177 # parse from file object 178 179 handle, filename = tempfile.mkstemp(suffix=".xml") 180 os.write(handle, self.root_str) 181 try: 182 f = open(filename, 'rb') 183 tree = self.etree.ElementTree() 184 root = tree.parse(f) 185 f.close() 186 self.assertEqual(self.etree.tostring(root), self.root_str) 187 finally: 188 os.close(handle) 189 os.remove(filename)
190
192 # (c)ElementTree class ElementTree has a 'parse' method that returns 193 # the root of the tree 194 195 # parse from unamed file object 196 f = SillyFileLike() 197 root = self.etree.ElementTree().parse(f) 198 self.assert_(root.tag.endswith('foo'))
199
201 # parse from unamed file object 202 f = LargeFileLike() 203 tree = self.etree.parse(f) 204 root = tree.getroot() 205 self.assert_(root.tag.endswith('root'))
206
208 class LocalError(Exception): 209 pass
210 class TestFile: 211 def read(*args): 212 raise LocalError
213 f = TestFile() 214 self.assertRaises(LocalError, self.etree.parse, f) 215
216 - def test_module_parse_fileobject_late_error(self):
217 class LocalError(Exception): 218 pass
219 class TestFile: 220 data = '<root>test</' 221 try: 222 next_char = iter(data).next 223 except AttributeError: 224 # Python 3 225 next_char = iter(data).__next__ 226 counter = 0 227 def read(self, amount=None): 228 if amount is None: 229 while True: 230 self.read(1) 231 else: 232 try: 233 self.counter += 1 234 return _bytes(self.next_char()) 235 except StopIteration: 236 raise LocalError 237 f = TestFile() 238 self.assertRaises(LocalError, self.etree.parse, f) 239 self.assertEquals(f.counter, len(f.data)+1) 240
241 - def test_module_parse_fileobject_type_error(self):
242 class TestFile: 243 def read(*args): 244 return 1
245 f = TestFile() 246 self.assertRaises(TypeError, self.etree.parse, f) 247 248
249 -class ETreeIOTestCase(IOTestCaseBase):
250 etree = etree
251 252 if ElementTree:
253 - class ElementTreeIOTestCase(IOTestCaseBase):
254 etree = ElementTree
255
256 -def test_suite():
257 suite = unittest.TestSuite() 258 suite.addTests([unittest.makeSuite(ETreeIOTestCase)]) 259 if ElementTree: 260 suite.addTests([unittest.makeSuite(ElementTreeIOTestCase)]) 261 return suite
262 263 if __name__ == '__main__': 264 print('to test use test.py %s' % __file__) 265