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

Source Code for Module lxml.tests.common_imports

  1  import gc 
  2  import os 
  3  import os.path 
  4  import re 
  5  import sys 
  6  import tempfile 
  7  import unittest 
  8  from contextlib import contextmanager 
  9   
 10  try: 
 11      import urlparse 
 12  except ImportError: 
 13      import urllib.parse as urlparse  
 14   
 15  try: 
 16      from urllib import pathname2url 
 17  except: 
 18      from urllib.request import pathname2url 
 19   
 20  from lxml import etree, html 
21 22 -def make_version_tuple(version_string):
23 return tuple( 24 int(part) if part.isdigit() else part 25 for part in re.findall('([0-9]+|[^0-9.]+)', version_string) 26 )
27 28 IS_PYPY = (getattr(sys, 'implementation', None) == 'pypy' or 29 getattr(sys, 'pypy_version_info', None) is not None) 30 31 IS_PYTHON3 = sys.version_info[0] >= 3 32 IS_PYTHON2 = sys.version_info[0] < 3 33 34 from xml.etree import ElementTree 35 36 if hasattr(ElementTree, 'VERSION'): 37 ET_VERSION = make_version_tuple(ElementTree.VERSION) 38 else: 39 ET_VERSION = (0,0,0) 40 41 if IS_PYTHON2: 42 from xml.etree import cElementTree 43 44 if hasattr(cElementTree, 'VERSION'): 45 CET_VERSION = make_version_tuple(cElementTree.VERSION) 46 else: 47 CET_VERSION = (0,0,0) 48 else: 49 CET_VERSION = (0, 0, 0) 50 cElementTree = None
51 52 53 -def filter_by_version(test_class, version_dict, current_version):
54 """Remove test methods that do not work with the current lib version. 55 """ 56 find_required_version = version_dict.get 57 def dummy_test_method(self): 58 pass
59 for name in dir(test_class): 60 expected_version = find_required_version(name, (0,0,0)) 61 if expected_version > current_version: 62 setattr(test_class, name, dummy_test_method) 63 64 import doctest 65 66 try: 67 next 68 except NameError:
69 - def next(it):
70 return it.next()
71 else: 72 locals()['next'] = next 73 74 75 try: 76 import pytest 77 except ImportError:
78 - class skipif(object):
79 "Using a class because a function would bind into a method when used in classes"
80 - def __init__(self, *args): pass
81 - def __call__(self, func, *args): return func
82 else: 83 skipif = pytest.mark.skipif
84 85 -def _get_caller_relative_path(filename, frame_depth=2):
86 module = sys.modules[sys._getframe(frame_depth).f_globals['__name__']] 87 return os.path.normpath(os.path.join( 88 os.path.dirname(getattr(module, '__file__', '')), filename))
89 90 from io import StringIO 91 92 unichr_escape = re.compile(r'\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}') 93 94 if sys.version_info[0] >= 3: 95 # Python 3 96 from builtins import str as unicode 97 from codecs import unicode_escape_decode 98 _chr = chr
99 - def _str(s, encoding="UTF-8"):
100 return unichr_escape.sub(lambda x: unicode_escape_decode(x.group(0))[0], s)
101 - def _bytes(s, encoding="UTF-8"):
102 return s.encode(encoding)
103 from io import BytesIO as _BytesIO
104 - def BytesIO(*args):
105 if args and isinstance(args[0], str): 106 args = (args[0].encode("UTF-8"),) 107 return _BytesIO(*args)
108 109 doctest_parser = doctest.DocTestParser() 110 _fix_unicode = re.compile(r'(\s+)u(["\'])').sub 111 _fix_exceptions = re.compile(r'(.*except [^(]*),\s*(.*:)').sub
112 - def make_doctest(filename):
113 filename = _get_caller_relative_path(filename) 114 doctests = read_file(filename) 115 doctests = _fix_unicode(r'\1\2', doctests) 116 doctests = _fix_exceptions(r'\1 as \2', doctests) 117 return doctest.DocTestCase( 118 doctest_parser.get_doctest( 119 doctests, {}, os.path.basename(filename), filename, 0))
120 else: 121 # Python 2 122 from __builtin__ import unicode 123 _chr = unichr
124 - def _str(s, encoding="UTF-8"):
125 s = unicode(s, encoding=encoding) 126 return unichr_escape.sub(lambda x: 127 x.group(0).decode('unicode-escape'), 128 s)
129 - def _bytes(s, encoding="UTF-8"):
130 return s
131 from io import BytesIO 132 133 doctest_parser = doctest.DocTestParser() 134 _fix_traceback = re.compile(r'^(\s*)(?:\w+\.)+(\w*(?:Error|Exception|Invalid):)', re.M).sub 135 _fix_exceptions = re.compile(r'(.*except [^(]*)\s+as\s+(.*:)').sub 136 _fix_bytes = re.compile(r'(\s+)b(["\'])').sub
137 - def make_doctest(filename):
138 filename = _get_caller_relative_path(filename) 139 doctests = read_file(filename) 140 doctests = _fix_traceback(r'\1\2', doctests) 141 doctests = _fix_exceptions(r'\1, \2', doctests) 142 doctests = _fix_bytes(r'\1\2', doctests) 143 return doctest.DocTestCase( 144 doctest_parser.get_doctest( 145 doctests, {}, os.path.basename(filename), filename, 0))
146 147 try: 148 skipIf = unittest.skipIf 149 except AttributeError:
150 - def skipIf(condition, why):
151 def _skip(thing): 152 import types 153 if isinstance(thing, (type, types.ClassType)): 154 return type(thing.__name__, (object,), {}) 155 else: 156 return None
157 if condition: 158 return _skip 159 return lambda thing: thing 160
161 162 -class HelperTestCase(unittest.TestCase):
163 - def tearDown(self):
164 gc.collect()
165
166 - def parse(self, text, parser=None):
167 f = BytesIO(text) if isinstance(text, bytes) else StringIO(text) 168 return etree.parse(f, parser=parser)
169
170 - def _rootstring(self, tree):
171 return etree.tostring(tree.getroot()).replace( 172 _bytes(' '), _bytes('')).replace(_bytes('\n'), _bytes(''))
173
174 175 -class SillyFileLike:
176 - def __init__(self, xml_data=_bytes('<foo><bar/></foo>')):
177 self.xml_data = xml_data
178
179 - def read(self, amount=None):
180 if self.xml_data: 181 if amount: 182 data = self.xml_data[:amount] 183 self.xml_data = self.xml_data[amount:] 184 else: 185 data = self.xml_data 186 self.xml_data = _bytes('') 187 return data 188 return _bytes('')
189
190 -class LargeFileLike:
191 - def __init__(self, charlen=100, depth=4, children=5):
192 self.data = BytesIO() 193 self.chars = _bytes('a') * charlen 194 self.children = range(children) 195 self.more = self.iterelements(depth)
196
197 - def iterelements(self, depth):
198 yield _bytes('<root>') 199 depth -= 1 200 if depth > 0: 201 for child in self.children: 202 for element in self.iterelements(depth): 203 yield element 204 yield self.chars 205 else: 206 yield self.chars 207 yield _bytes('</root>')
208
209 - def read(self, amount=None):
210 data = self.data 211 append = data.write 212 if amount: 213 for element in self.more: 214 append(element) 215 if data.tell() >= amount: 216 break 217 else: 218 for element in self.more: 219 append(element) 220 result = data.getvalue() 221 data.seek(0) 222 data.truncate() 223 if amount: 224 append(result[amount:]) 225 result = result[:amount] 226 return result
227
228 -class LargeFileLikeUnicode(LargeFileLike):
229 - def __init__(self, charlen=100, depth=4, children=5):
230 LargeFileLike.__init__(self, charlen, depth, children) 231 self.data = StringIO() 232 self.chars = _str('a') * charlen 233 self.more = self.iterelements(depth)
234
235 - def iterelements(self, depth):
236 yield _str('<root>') 237 depth -= 1 238 if depth > 0: 239 for child in self.children: 240 for element in self.iterelements(depth): 241 yield element 242 yield self.chars 243 else: 244 yield self.chars 245 yield _str('</root>')
246
247 -def fileInTestDir(name):
248 _testdir = os.path.dirname(__file__) 249 return os.path.join(_testdir, name)
250
251 -def path2url(path):
252 return urlparse.urljoin( 253 'file:', pathname2url(path))
254
255 -def fileUrlInTestDir(name):
256 return path2url(fileInTestDir(name))
257
258 -def read_file(name, mode='r'):
259 with open(name, mode) as f: 260 data = f.read() 261 return data
262
263 -def write_to_file(name, data, mode='w'):
264 with open(name, mode) as f: 265 f.write(data)
266
267 -def readFileInTestDir(name, mode='r'):
268 return read_file(fileInTestDir(name), mode)
269
270 -def canonicalize(xml):
271 tree = etree.parse(BytesIO(xml) if isinstance(xml, bytes) else StringIO(xml)) 272 f = BytesIO() 273 tree.write_c14n(f) 274 return f.getvalue()
275
276 277 @contextmanager 278 -def tmpfile(**kwargs):
279 handle, filename = tempfile.mkstemp(**kwargs) 280 try: 281 yield filename 282 finally: 283 os.close(handle) 284 os.remove(filename)
285