Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

_in_process.py 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. """This is invoked in a subprocess to call the build backend hooks.
  2. It expects:
  3. - Command line args: hook_name, control_dir
  4. - Environment variable: PEP517_BUILD_BACKEND=entry.point:spec
  5. - control_dir/input.json:
  6. - {"kwargs": {...}}
  7. Results:
  8. - control_dir/output.json
  9. - {"return_val": ...}
  10. """
  11. from glob import glob
  12. from importlib import import_module
  13. import os
  14. from os.path import join as pjoin
  15. import re
  16. import shutil
  17. import sys
  18. # This is run as a script, not a module, so it can't do a relative import
  19. import compat
  20. def _build_backend():
  21. """Find and load the build backend"""
  22. ep = os.environ['PEP517_BUILD_BACKEND']
  23. mod_path, _, obj_path = ep.partition(':')
  24. obj = import_module(mod_path)
  25. if obj_path:
  26. for path_part in obj_path.split('.'):
  27. obj = getattr(obj, path_part)
  28. return obj
  29. def get_requires_for_build_wheel(config_settings):
  30. """Invoke the optional get_requires_for_build_wheel hook
  31. Returns [] if the hook is not defined.
  32. """
  33. backend = _build_backend()
  34. try:
  35. hook = backend.get_requires_for_build_wheel
  36. except AttributeError:
  37. return []
  38. else:
  39. return hook(config_settings)
  40. def prepare_metadata_for_build_wheel(metadata_directory, config_settings):
  41. """Invoke optional prepare_metadata_for_build_wheel
  42. Implements a fallback by building a wheel if the hook isn't defined.
  43. """
  44. backend = _build_backend()
  45. try:
  46. hook = backend.prepare_metadata_for_build_wheel
  47. except AttributeError:
  48. return _get_wheel_metadata_from_wheel(backend, metadata_directory,
  49. config_settings)
  50. else:
  51. return hook(metadata_directory, config_settings)
  52. WHEEL_BUILT_MARKER = 'PEP517_ALREADY_BUILT_WHEEL'
  53. def _dist_info_files(whl_zip):
  54. """Identify the .dist-info folder inside a wheel ZipFile."""
  55. res = []
  56. for path in whl_zip.namelist():
  57. m = re.match(r'[^/\\]+-[^/\\]+\.dist-info/', path)
  58. if m:
  59. res.append(path)
  60. if res:
  61. return res
  62. raise Exception("No .dist-info folder found in wheel")
  63. def _get_wheel_metadata_from_wheel(backend, metadata_directory, config_settings):
  64. """Build a wheel and extract the metadata from it.
  65. Fallback for when the build backend does not define the 'get_wheel_metadata'
  66. hook.
  67. """
  68. from zipfile import ZipFile
  69. whl_basename = backend.build_wheel(metadata_directory, config_settings)
  70. with open(os.path.join(metadata_directory, WHEEL_BUILT_MARKER), 'wb'):
  71. pass # Touch marker file
  72. whl_file = os.path.join(metadata_directory, whl_basename)
  73. with ZipFile(whl_file) as zipf:
  74. dist_info = _dist_info_files(zipf)
  75. zipf.extractall(path=metadata_directory, members=dist_info)
  76. return dist_info[0].split('/')[0]
  77. def _find_already_built_wheel(metadata_directory):
  78. """Check for a wheel already built during the get_wheel_metadata hook.
  79. """
  80. if not metadata_directory:
  81. return None
  82. metadata_parent = os.path.dirname(metadata_directory)
  83. if not os.path.isfile(pjoin(metadata_parent, WHEEL_BUILT_MARKER)):
  84. return None
  85. whl_files = glob(os.path.join(metadata_parent, '*.whl'))
  86. if not whl_files:
  87. print('Found wheel built marker, but no .whl files')
  88. return None
  89. if len(whl_files) > 1:
  90. print('Found multiple .whl files; unspecified behaviour. '
  91. 'Will call build_wheel.')
  92. return None
  93. # Exactly one .whl file
  94. return whl_files[0]
  95. def build_wheel(wheel_directory, config_settings, metadata_directory=None):
  96. """Invoke the mandatory build_wheel hook.
  97. If a wheel was already built in the prepare_metadata_for_build_wheel fallback, this
  98. will copy it rather than rebuilding the wheel.
  99. """
  100. prebuilt_whl = _find_already_built_wheel(metadata_directory)
  101. if prebuilt_whl:
  102. shutil.copy2(prebuilt_whl, wheel_directory)
  103. return os.path.basename(prebuilt_whl)
  104. return _build_backend().build_wheel(wheel_directory, config_settings,
  105. metadata_directory)
  106. def get_requires_for_build_sdist(config_settings):
  107. """Invoke the optional get_requires_for_build_wheel hook
  108. Returns [] if the hook is not defined.
  109. """
  110. backend = _build_backend()
  111. try:
  112. hook = backend.get_requires_for_build_sdist
  113. except AttributeError:
  114. return []
  115. else:
  116. return hook(config_settings)
  117. class _DummyException(Exception):
  118. """Nothing should ever raise this exception"""
  119. class GotUnsupportedOperation(Exception):
  120. """For internal use when backend raises UnsupportedOperation"""
  121. def build_sdist(sdist_directory, config_settings):
  122. """Invoke the mandatory build_sdist hook."""
  123. backend = _build_backend()
  124. try:
  125. return backend.build_sdist(sdist_directory, config_settings)
  126. except getattr(backend, 'UnsupportedOperation', _DummyException):
  127. raise GotUnsupportedOperation
  128. HOOK_NAMES = {
  129. 'get_requires_for_build_wheel',
  130. 'prepare_metadata_for_build_wheel',
  131. 'build_wheel',
  132. 'get_requires_for_build_sdist',
  133. 'build_sdist',
  134. }
  135. def main():
  136. if len(sys.argv) < 3:
  137. sys.exit("Needs args: hook_name, control_dir")
  138. hook_name = sys.argv[1]
  139. control_dir = sys.argv[2]
  140. if hook_name not in HOOK_NAMES:
  141. sys.exit("Unknown hook: %s" % hook_name)
  142. hook = globals()[hook_name]
  143. hook_input = compat.read_json(pjoin(control_dir, 'input.json'))
  144. json_out = {'unsupported': False, 'return_val': None}
  145. try:
  146. json_out['return_val'] = hook(**hook_input['kwargs'])
  147. except GotUnsupportedOperation:
  148. json_out['unsupported'] = True
  149. compat.write_json(json_out, pjoin(control_dir, 'output.json'), indent=2)
  150. if __name__ == '__main__':
  151. main()