Skip to content

Proof of Concept: Bootstrap backend from specified directory #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pep517/_in_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
13 changes: 8 additions & 5 deletions pep517/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -137,16 +138,18 @@ def build_sdist(self, sdist_directory, config_settings=None):
})

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
# letters, digits and _, . and : characters, and will be used as a
# 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'),
Expand All @@ -156,7 +159,7 @@ def _call_hook(self, hook_name, kwargs):
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'))
Expand Down
20 changes: 20 additions & 0 deletions tests/samples/bootstrap_pkg/mybackend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# A "bootstrap backend" for testing purposes
def get_requires_for_build_wheel(config_settings=None):
return ['wheel', 'sentinel']


def get_requires_for_build_sdist(config_settings=None):
return ['sdist_sentinel']


def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None):
pass


def build_wheel(wheel_directory, config_settings=None,
metadata_directory=None):
pass


def build_sdist(sdist_directory, config_settings):
pass
4 changes: 4 additions & 0 deletions tests/samples/bootstrap_pkg/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[build-system]
requires=[]
build-backend="mybackend"
bootstrap-backend-location="."
16 changes: 15 additions & 1 deletion tests/test_call_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down Expand Up @@ -103,3 +107,13 @@ def test_build_sdist_unsupported():
with modified_env({'PYTHONPATH': BUILDSYS_PKGS}):
with pytest.raises(UnsupportedOperation):
hooks.build_sdist(sdistdir, {'test_unsupported': True})


def test_bootstrap_backend():
hooks = get_hooks('bootstrap_pkg')
with modified_env({'PYTHONPATH': ''}):
wheel_reqs = hooks.get_requires_for_build_wheel({})
assert wheel_reqs == ['wheel', 'sentinel']

sdist_reqs = hooks.get_requires_for_build_sdist({})
assert sdist_reqs == ['sdist_sentinel']