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

# Source Code for Module lxml.tests.common_imports

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