Skip to content

Commit 30a3c00

Browse files
committed
Only use build_editable when the build backend supports it.
1 parent 08b94ca commit 30a3c00

File tree

2 files changed

+62
-26
lines changed

2 files changed

+62
-26
lines changed

pex/jobs.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,27 @@ def __repr__(me):
381381

382382
return Map()
383383

384+
def or_else(self, func):
385+
# type: (Callable[[Job.Error], SpawnedJob[_T]]) -> SpawnedJob[_T]
386+
387+
class OrElse(SpawnedJob):
388+
def await_result(me):
389+
# type: () -> _T
390+
try:
391+
return self.await_result()
392+
except Job.Error as e:
393+
return func(e).await_result()
394+
395+
def kill(me):
396+
# type: () -> None
397+
self.kill()
398+
399+
def __repr__(me):
400+
# type: () -> str
401+
return "{job}.or_else({func})".format(job=self, func=func)
402+
403+
return OrElse()
404+
384405

385406
# If `cpu_count` fails, we default to 2. This is relatively arbitrary, based on what seems to be
386407
# common in CI.

pex/resolver.py

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
from pex.exceptions import production_assert
4141
from pex.fingerprinted_distribution import FingerprintedDistribution
4242
from pex.installed_wheel import InstalledWheel
43-
from pex.jobs import Raise, SpawnedJob, execute_parallel, iter_map_parallel
43+
from pex.jobs import Job, Raise, SpawnedJob, execute_parallel, iter_map_parallel
4444
from pex.network_configuration import NetworkConfiguration
4545
from pex.orderedset import OrderedSet
4646
from pex.pep_425 import CompatibilityTags
@@ -1060,43 +1060,58 @@ def _spawn_wheel_build(self, build_request):
10601060
# type: (BuildRequest) -> SpawnedJob[BuildResult]
10611061
source_path, editable = build_request.prepare()
10621062
build_result = build_request.result(source_path)
1063+
1064+
def spawn_build_wheel():
1065+
# type: () -> SpawnedJob[BuildResult]
1066+
build_job = get_pip(
1067+
interpreter=build_request.target.get_interpreter(),
1068+
version=self._pip_version,
1069+
resolver=self._resolver,
1070+
extra_requirements=(
1071+
self._package_index_configuration.extra_pip_requirements
1072+
if self._package_index_configuration is not None
1073+
else ()
1074+
),
1075+
).spawn_build_wheels(
1076+
requirements=[source_path],
1077+
wheel_dir=build_result.build_dir,
1078+
package_index_configuration=self._package_index_configuration,
1079+
interpreter=build_request.target.get_interpreter(),
1080+
build_configuration=self._build_configuration,
1081+
verify=self._verify_wheels,
1082+
)
1083+
return SpawnedJob.wait(job=build_job, result=build_result)
1084+
10631085
if editable:
10641086
if not self._resolver:
10651087
raise BuildError(
10661088
"A resolver is required to build an local editable project.\n"
10671089
"Cannot build: {project}".format(project=source_path)
10681090
)
10691091

1092+
def maybe_spawn_build_wheel(err):
1093+
# type: (Job.Error) -> SpawnedJob[BuildResult]
1094+
if pep_517.is_hook_unavailable_error(err):
1095+
return spawn_build_wheel()
1096+
raise err
1097+
10701098
# N.B.: We're forced to do this ourselves because Pip refuses to honor its
10711099
# otherwise apparently supported `pip wheel -e ...` CLI interface. Pip ignores -e and
10721100
# silently builds a full wheel :/.
10731101
# See: https://github.com/pypa/pip/issues/12414
1074-
return pep_517.spawn_build_editable(
1075-
project_directory=source_path,
1076-
wheel_dir=build_result.build_dir,
1077-
target=build_request.target,
1078-
resolver=self._resolver,
1079-
pip_version=self._pip_version,
1080-
).map(lambda _: build_result)
1102+
return (
1103+
pep_517.spawn_build_editable(
1104+
project_directory=source_path,
1105+
wheel_dir=build_result.build_dir,
1106+
target=build_request.target,
1107+
resolver=self._resolver,
1108+
pip_version=self._pip_version,
1109+
)
1110+
.map(lambda _: build_result)
1111+
.or_else(maybe_spawn_build_wheel)
1112+
)
10811113

1082-
build_job = get_pip(
1083-
interpreter=build_request.target.get_interpreter(),
1084-
version=self._pip_version,
1085-
resolver=self._resolver,
1086-
extra_requirements=(
1087-
self._package_index_configuration.extra_pip_requirements
1088-
if self._package_index_configuration is not None
1089-
else ()
1090-
),
1091-
).spawn_build_wheels(
1092-
requirements=[source_path],
1093-
wheel_dir=build_result.build_dir,
1094-
package_index_configuration=self._package_index_configuration,
1095-
interpreter=build_request.target.get_interpreter(),
1096-
build_configuration=self._build_configuration,
1097-
verify=self._verify_wheels,
1098-
)
1099-
return SpawnedJob.wait(job=build_job, result=build_result)
1114+
return spawn_build_wheel()
11001115

11011116
def build_wheels(
11021117
self,

0 commit comments

Comments
 (0)