import_test.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. from __future__ import print_function
  2. import os
  3. import re
  4. import sys
  5. import time
  6. import traceback
  7. import __res
  8. from __res import importer
  9. def check_imports(no_check=(), extra=(), skip_func=None, py_main=None):
  10. """
  11. tests all bundled modules are importable
  12. just add
  13. "PEERDIR(library/python/import_test)" to your CMakeLists.txt and
  14. "from import_test import test_imports" to your python test source file.
  15. """
  16. str_ = lambda s: s
  17. if not isinstance(b'', str):
  18. str_ = lambda s: s.decode('UTF-8')
  19. exceptions = list(no_check)
  20. for key, _ in __res.iter_keys(b'py/no_check_imports/'):
  21. exceptions += str_(__res.find(key)).split()
  22. if exceptions:
  23. exceptions.sort()
  24. print('NO_CHECK_IMPORTS', ' '.join(exceptions))
  25. patterns = [re.escape(s).replace(r'\*', r'.*') for s in exceptions]
  26. rx = re.compile('^({})$'.format('|'.join(patterns)))
  27. failed = []
  28. import_times = {}
  29. norm = lambda s: s[:-9] if s.endswith('.__init__') else s
  30. modules = sys.extra_modules | set(extra)
  31. modules = sorted(modules, key=norm)
  32. if py_main:
  33. modules = [py_main] + modules
  34. for module in modules:
  35. if module not in extra and (rx.search(module) or skip_func and skip_func(module)):
  36. print('SKIP', module)
  37. continue
  38. name = module.rsplit('.', 1)[-1]
  39. if name == '__main__' and 'if __name__ ==' not in importer.get_source(module):
  40. print('SKIP', module, '''without "if __name__ == '__main__'" check''')
  41. continue
  42. def print_backtrace_marked(e):
  43. tb_exc = traceback.format_exception(*e)
  44. for item in tb_exc:
  45. for l in item.splitlines():
  46. print('FAIL:', l, file=sys.stderr)
  47. try:
  48. print('TRY', module)
  49. # XXX waiting for py3 to use print(..., flush=True)
  50. sys.stdout.flush()
  51. s = time.time()
  52. if module == '__main__':
  53. importer.load_module('__main__', '__main__py')
  54. elif module.endswith('.__init__'):
  55. __import__(module[:-len('.__init__')])
  56. else:
  57. __import__(module)
  58. delay = time.time() - s
  59. import_times[str(module)] = delay
  60. print('OK ', module, '{:.3f}s'.format(delay))
  61. except Exception as e:
  62. print('FAIL:', module, e, file=sys.stderr)
  63. print_backtrace_marked(sys.exc_info())
  64. failed.append('{}: {}'.format(module, e))
  65. except:
  66. e = sys.exc_info()
  67. print('FAIL:', module, e, file=sys.stderr)
  68. print_backtrace_marked(e)
  69. failed.append('{}: {}'.format(module, e))
  70. raise
  71. print("Slowest imports:")
  72. for m, t in sorted(import_times.items(), key=lambda x: x[1], reverse=True)[:30]:
  73. print(' ', '{:.3f}s'.format(t), m)
  74. if failed:
  75. raise ImportError('modules not imported:\n' + '\n'.join(failed))
  76. test_imports = check_imports
  77. def main():
  78. skip_names = sys.argv[1:]
  79. os.environ['Y_PYTHON_IMPORT_TEST'] = ''
  80. # We should initialize Django before importing any applications
  81. if os.getenv('DJANGO_SETTINGS_MODULE'):
  82. try:
  83. import django
  84. except ImportError:
  85. pass
  86. else:
  87. django.setup()
  88. py_main = __res.find('PY_MAIN')
  89. if py_main:
  90. py_main_module = py_main.split(b':', 1)[0].decode('UTF-8')
  91. else:
  92. py_main_module = None
  93. try:
  94. check_imports(no_check=skip_names, py_main=py_main_module)
  95. except:
  96. sys.exit(1)