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