Skip to content

Commit 69c8010

Browse files
committed
Raise HookMissing instead of falling back, if requested.
For now this only applies to `prepare_metadata_for_build_wheel`.
1 parent d977cc6 commit 69c8010

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

pep517/_in_process.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ def __init__(self, message):
3838
self.message = message
3939

4040

41+
class HookMissing(Exception):
42+
"""Raised if a hook is missing and we are not executing the fallback"""
43+
44+
4145
def contained_in(filename, directory):
4246
"""Test if a file is located within the given directory."""
4347
filename = os.path.normcase(os.path.abspath(filename))
@@ -87,15 +91,19 @@ def get_requires_for_build_wheel(config_settings):
8791
return hook(config_settings)
8892

8993

90-
def prepare_metadata_for_build_wheel(metadata_directory, config_settings):
94+
def prepare_metadata_for_build_wheel(
95+
metadata_directory, config_settings, _allow_fallback):
9196
"""Invoke optional prepare_metadata_for_build_wheel
9297
93-
Implements a fallback by building a wheel if the hook isn't defined.
98+
Implements a fallback by building a wheel if the hook isn't defined,
99+
unless _allow_fallback is False in which case HookMissing is raised.
94100
"""
95101
backend = _build_backend()
96102
try:
97103
hook = backend.prepare_metadata_for_build_wheel
98104
except AttributeError:
105+
if not _allow_fallback:
106+
raise HookMissing()
99107
return _get_wheel_metadata_from_wheel(backend, metadata_directory,
100108
config_settings)
101109
else:
@@ -239,6 +247,8 @@ def main():
239247
except GotUnsupportedOperation as e:
240248
json_out['unsupported'] = True
241249
json_out['traceback'] = e.traceback
250+
except HookMissing:
251+
json_out['hook_missing'] = True
242252

243253
compat.write_json(json_out, pjoin(control_dir, 'output.json'), indent=2)
244254

pep517/wrappers.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ def __init__(self, backend_name, backend_path, message):
3535
self.message = message
3636

3737

38+
class HookMissing(Exception):
39+
"""Will be raised on missing hooks."""
40+
41+
3842
class UnsupportedOperation(Exception):
3943
"""May be raised by build_sdist if the backend indicates that it can't."""
4044
def __init__(self, traceback):
@@ -134,18 +138,21 @@ def get_requires_for_build_wheel(self, config_settings=None):
134138
})
135139

136140
def prepare_metadata_for_build_wheel(
137-
self, metadata_directory, config_settings=None):
141+
self, metadata_directory, config_settings=None,
142+
_allow_fallback=True):
138143
"""Prepare a *.dist-info folder with metadata for this project.
139144
140145
Returns the name of the newly created folder.
141146
142147
If the build backend defines a hook with this name, it will be called
143148
in a subprocess. If not, the backend will be asked to build a wheel,
144-
and the dist-info extracted from that.
149+
and the dist-info extracted from that (unless _allow_fallback is
150+
False).
145151
"""
146152
return self._call_hook('prepare_metadata_for_build_wheel', {
147153
'metadata_directory': abspath(metadata_directory),
148154
'config_settings': config_settings,
155+
'_allow_fallback': _allow_fallback,
149156
})
150157

151158
def build_wheel(
@@ -237,6 +244,8 @@ def _call_hook(self, hook_name, kwargs):
237244
backend_path=self.backend_path,
238245
message=data.get('backend_error', '')
239246
)
247+
if data.get('hook_missing'):
248+
raise HookMissing()
240249
return data['return_val']
241250

242251

tests/test_hook_fallbacks.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from os.path import dirname, abspath, join as pjoin
2+
import pytest
23
import pytoml
34
from testpath import modified_env, assert_isfile
45
from testpath.tempdir import TemporaryDirectory
56

6-
from pep517.wrappers import Pep517HookCaller
7+
from pep517.wrappers import HookMissing, Pep517HookCaller
78

89
SAMPLES_DIR = pjoin(dirname(abspath(__file__)), 'samples')
910
BUILDSYS_PKGS = pjoin(SAMPLES_DIR, 'buildsys_pkgs')
@@ -37,3 +38,14 @@ def test_prepare_metadata_for_build_wheel():
3738
hooks.prepare_metadata_for_build_wheel(metadatadir, {})
3839

3940
assert_isfile(pjoin(metadatadir, 'pkg2-0.5.dist-info', 'METADATA'))
41+
42+
43+
def test_prepare_metadata_for_build_wheel_no_fallback():
44+
hooks = get_hooks('pkg2')
45+
46+
with TemporaryDirectory() as metadatadir:
47+
with modified_env({'PYTHONPATH': BUILDSYS_PKGS}):
48+
with pytest.raises(HookMissing):
49+
hooks.prepare_metadata_for_build_wheel(
50+
metadatadir, {}, _allow_fallback=False
51+
)

0 commit comments

Comments
 (0)