util.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. # Filter DeprecationWarnings until the code has been revised
  2. import warnings
  3. warnings.filterwarnings("ignore", "the imp module is deprecated in")
  4. warnings.filterwarnings("ignore", "imp_walk will be removed in a future")
  5. import os
  6. import imp
  7. import sys
  8. import re
  9. import marshal
  10. import warnings
  11. import inspect
  12. try:
  13. unicode
  14. except NameError:
  15. unicode = str
  16. from ._compat import StringIO, BytesIO, get_instructions, _READ_MODE
  17. def imp_find_module(name, path=None):
  18. """
  19. same as imp.find_module, but handles dotted names
  20. """
  21. names = name.split('.')
  22. if path is not None:
  23. if isinstance(path, (str, unicode)):
  24. path = [os.path.realpath(path)]
  25. for name in names:
  26. result = imp.find_module(name, path)
  27. if result[0] is not None:
  28. result[0].close()
  29. path = [result[1]]
  30. return result
  31. def _check_importer_for_path(name, path_item):
  32. try:
  33. importer = sys.path_importer_cache[path_item]
  34. except KeyError:
  35. for path_hook in sys.path_hooks:
  36. try:
  37. importer = path_hook(path_item)
  38. break
  39. except ImportError:
  40. pass
  41. else:
  42. importer = None
  43. sys.path_importer_cache.setdefault(path_item, importer)
  44. if importer is None:
  45. try:
  46. return imp.find_module(name, [path_item])
  47. except ImportError:
  48. return None
  49. return importer.find_module(name)
  50. def imp_walk(name):
  51. """
  52. yields namepart, tuple_or_importer for each path item
  53. raise ImportError if a name can not be found.
  54. """
  55. warnings.warn(
  56. "imp_walk will be removed in a future version",
  57. DeprecationWarning)
  58. if name in sys.builtin_module_names:
  59. yield name, (None, None, ("", "", imp.C_BUILTIN))
  60. return
  61. paths = sys.path
  62. res = None
  63. for namepart in name.split('.'):
  64. for path_item in paths:
  65. res = _check_importer_for_path(namepart, path_item)
  66. if hasattr(res, 'load_module'):
  67. if res.path.endswith('.py') or res.path.endswith('.pyw'):
  68. fp = StringIO(res.get_source(namepart))
  69. res = (fp, res.path, ('.py', _READ_MODE, imp.PY_SOURCE))
  70. elif res.path.endswith('.pyc') or res.path.endswith('.pyo'):
  71. co = res.get_code(namepart)
  72. fp = BytesIO(
  73. imp.get_magic() + b'\0\0\0\0' + marshal.dumps(co))
  74. res = (fp, res.path, ('.pyc', 'rb', imp.PY_COMPILED))
  75. else:
  76. res = (
  77. None,
  78. res.path,
  79. (
  80. os.path.splitext(res.path)[-1],
  81. 'rb',
  82. imp.C_EXTENSION
  83. )
  84. )
  85. break
  86. elif isinstance(res, tuple):
  87. break
  88. else:
  89. break
  90. yield namepart, res
  91. paths = [os.path.join(path_item, namepart)]
  92. else:
  93. return
  94. raise ImportError('No module named %s' % (name,))
  95. cookie_re = re.compile(br"coding[:=]\s*([-\w.]+)")
  96. if sys.version_info[0] == 2:
  97. default_encoding = 'ascii'
  98. else:
  99. default_encoding = 'utf-8'
  100. def guess_encoding(fp):
  101. for i in range(2):
  102. ln = fp.readline()
  103. m = cookie_re.search(ln)
  104. if m is not None:
  105. return m.group(1).decode('ascii')
  106. return default_encoding
  107. def iterate_instructions(code_object):
  108. """Delivers the byte-code instructions as a continuous stream.
  109. Yields `dis.Instruction`. After each code-block (`co_code`), `None` is
  110. yielded to mark the end of the block and to interrupt the steam.
  111. """
  112. yield from get_instructions(code_object)
  113. yield None
  114. # For each constant in this code object that is itself a code object,
  115. # parse this constant in the same manner.
  116. for constant in code_object.co_consts:
  117. if inspect.iscode(constant):
  118. yield from iterate_instructions(constant)