backward.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
  2. # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
  3. """Add things to old Pythons so I can pretend they are newer."""
  4. # This file does lots of tricky stuff, so disable a bunch of pylint warnings.
  5. # pylint: disable=redefined-builtin
  6. # pylint: disable=unused-import
  7. # pxlint: disable=no-name-in-module
  8. import sys
  9. from coverage import env
  10. # Pythons 2 and 3 differ on where to get StringIO.
  11. try:
  12. from cStringIO import StringIO
  13. except ImportError:
  14. from io import StringIO
  15. # In py3, ConfigParser was renamed to the more-standard configparser
  16. try:
  17. import configparser
  18. except ImportError:
  19. import ConfigParser as configparser
  20. # What's a string called?
  21. try:
  22. string_class = basestring
  23. except NameError:
  24. string_class = str
  25. # What's a Unicode string called?
  26. try:
  27. unicode_class = unicode
  28. except NameError:
  29. unicode_class = str
  30. # Where do pickles come from?
  31. try:
  32. import cPickle as pickle
  33. except ImportError:
  34. import pickle
  35. # range or xrange?
  36. try:
  37. range = xrange
  38. except NameError:
  39. range = range # pylint: disable=redefined-variable-type
  40. # shlex.quote is new, but there's an undocumented implementation in "pipes",
  41. # who knew!?
  42. try:
  43. from shlex import quote as shlex_quote
  44. except ImportError:
  45. # Useful function, available under a different (undocumented) name
  46. # in Python versions earlier than 3.3.
  47. from pipes import quote as shlex_quote
  48. # A function to iterate listlessly over a dict's items.
  49. try:
  50. {}.iteritems
  51. except AttributeError:
  52. def iitems(d):
  53. """Produce the items from dict `d`."""
  54. return d.items()
  55. else:
  56. def iitems(d):
  57. """Produce the items from dict `d`."""
  58. return d.iteritems()
  59. # Getting the `next` function from an iterator is different in 2 and 3.
  60. try:
  61. iter([]).next
  62. except AttributeError:
  63. def iternext(seq):
  64. """Get the `next` function for iterating over `seq`."""
  65. return iter(seq).__next__
  66. else:
  67. def iternext(seq):
  68. """Get the `next` function for iterating over `seq`."""
  69. return iter(seq).next
  70. # Python 3.x is picky about bytes and strings, so provide methods to
  71. # get them right, and make them no-ops in 2.x
  72. if env.PY3:
  73. def to_bytes(s):
  74. """Convert string `s` to bytes."""
  75. return s.encode('utf8')
  76. def binary_bytes(byte_values):
  77. """Produce a byte string with the ints from `byte_values`."""
  78. return bytes(byte_values)
  79. def bytes_to_ints(bytes_value):
  80. """Turn a bytes object into a sequence of ints."""
  81. # In Python 3, iterating bytes gives ints.
  82. return bytes_value
  83. else:
  84. def to_bytes(s):
  85. """Convert string `s` to bytes (no-op in 2.x)."""
  86. return s
  87. def binary_bytes(byte_values):
  88. """Produce a byte string with the ints from `byte_values`."""
  89. return "".join(chr(b) for b in byte_values)
  90. def bytes_to_ints(bytes_value):
  91. """Turn a bytes object into a sequence of ints."""
  92. for byte in bytes_value:
  93. yield ord(byte)
  94. try:
  95. # In Python 2.x, the builtins were in __builtin__
  96. BUILTINS = sys.modules['__builtin__']
  97. except KeyError:
  98. # In Python 3.x, they're in builtins
  99. BUILTINS = sys.modules['builtins']
  100. # imp was deprecated in Python 3.3
  101. try:
  102. import importlib
  103. import importlib.util
  104. imp = None
  105. except ImportError:
  106. importlib = None
  107. # We only want to use importlib if it has everything we need.
  108. try:
  109. importlib_util_find_spec = importlib.util.find_spec
  110. except Exception:
  111. import imp
  112. importlib_util_find_spec = None
  113. # What is the .pyc magic number for this version of Python?
  114. try:
  115. PYC_MAGIC_NUMBER = importlib.util.MAGIC_NUMBER
  116. except AttributeError:
  117. PYC_MAGIC_NUMBER = imp.get_magic()
  118. def import_local_file(modname, modfile=None):
  119. """Import a local file as a module.
  120. Opens a file in the current directory named `modname`.py, imports it
  121. as `modname`, and returns the module object. `modfile` is the file to
  122. import if it isn't in the current directory.
  123. """
  124. try:
  125. from importlib.machinery import SourceFileLoader
  126. except ImportError:
  127. SourceFileLoader = None
  128. if modfile is None:
  129. modfile = modname + '.py'
  130. if SourceFileLoader:
  131. mod = SourceFileLoader(modname, modfile).load_module()
  132. else:
  133. for suff in imp.get_suffixes(): # pragma: part covered
  134. if suff[0] == '.py':
  135. break
  136. with open(modfile, 'r') as f:
  137. # pylint: disable=undefined-loop-variable
  138. mod = imp.load_module(modname, f, modfile, suff)
  139. return mod