Prototype implementation of loading a self-hosting backend

bootstrap-backend
Thomas Kluyver 4 years ago
parent 2a8dcf5963
commit ce8b84964a
  1. 8
      pep517/_in_process.py
  2. 13
      pep517/wrappers.py
  3. 9
      tests/samples/bootstrap_pkg/mybackend.py
  4. 6
      tests/test_call_hooks.py

@ -33,10 +33,18 @@ def _build_backend():
"""Find and load the build backend"""
ep = os.environ['PEP517_BUILD_BACKEND']
mod_path, _, obj_path = ep.partition(':')
backend_locn = os.environ.get('PEP517_BACKEND_LOCN', None)
if backend_locn is not None:
sys.path.insert(0, backend_locn)
try:
obj = import_module(mod_path)
except ImportError:
raise BackendUnavailable(traceback.format_exc())
finally:
if backend_locn is not None:
sys.path.pop(0)
if obj_path:
for path_part in obj_path.split('.'):
obj = getattr(obj, path_part)

@ -47,9 +47,10 @@ class Pep517HookCaller(object):
source_dir : The path to the source directory, containing pyproject.toml.
backend : The build backend spec, as per PEP 517, from pyproject.toml.
"""
def __init__(self, source_dir, build_backend):
def __init__(self, source_dir, build_backend, bootstrap_backend_locn=None):
self.source_dir = abspath(source_dir)
self.build_backend = build_backend
self.bootstrap_backend_locn = bootstrap_backend_locn
self._subprocess_runner = default_subprocess_runner
# TODO: Is this over-engineered? Maybe frontends only need to
@ -137,6 +138,10 @@ class Pep517HookCaller(object):
})
def _call_hook(self, hook_name, kwargs):
envvars = {'PEP517_BUILD_BACKEND': self.build_backend}
if self.bootstrap_backend_locn is not None:
envvars['PEP517_BACKEND_LOCN'] = self.bootstrap_backend_locn
# On Python 2, pytoml returns Unicode values (which is correct) but the
# environment passed to check_call needs to contain string values. We
# convert here by encoding using ASCII (the backend can only contain
@ -144,9 +149,7 @@ class Pep517HookCaller(object):
# Python identifier, so non-ASCII content is wrong on Python 2 in
# any case).
if sys.version_info[0] == 2:
build_backend = self.build_backend.encode('ASCII')
else:
build_backend = self.build_backend
envvars = {k: v.encode('ASCII') for (k, v) in envvars.items()}
with tempdir() as td:
compat.write_json({'kwargs': kwargs}, pjoin(td, 'input.json'),
@ -156,7 +159,7 @@ class Pep517HookCaller(object):
self._subprocess_runner(
[sys.executable, _in_proc_script, hook_name, td],
cwd=self.source_dir,
extra_environ={'PEP517_BUILD_BACKEND': build_backend}
extra_environ=envvars,
)
data = compat.read_json(pjoin(td, 'output.json'))

@ -1,9 +1,9 @@
# A "bootstrap backend" for testing purposes
def get_requires_for_build_wheel():
def get_requires_for_build_wheel(config_settings=None):
return ['wheel', 'sentinel']
def get_requires_for_build_sdist():
def get_requires_for_build_sdist(config_settings=None):
return ['sdist_sentinel']
@ -11,9 +11,10 @@ def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
pass
def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
def build_wheel(wheel_directory, config_settings=None,
metadata_directory=None):
pass
def build_sdist(*args, **kwargs):
def build_sdist(sdist_directory, config_settings):
pass

@ -18,7 +18,11 @@ def get_hooks(pkg):
source_dir = pjoin(SAMPLES_DIR, pkg)
with open(pjoin(source_dir, 'pyproject.toml')) as f:
data = pytoml.load(f)
return Pep517HookCaller(source_dir, data['build-system']['build-backend'])
buildsys = data['build-system']
return Pep517HookCaller(
source_dir, buildsys['build-backend'],
bootstrap_backend_locn=buildsys.get('bootstrap-backend-location')
)
def test_missing_backend_gives_exception():

Loading…
Cancel
Save