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