Skip to content

Commit 17b896c

Browse files
committed
Add support for gathering all requirements needed to build a wheel for a project.
1 parent 46a576a commit 17b896c

File tree

3 files changed

+43
-13
lines changed

3 files changed

+43
-13
lines changed

pex/build_system/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
#
1111
# See: https://peps.python.org/pep-0517/#source-trees
1212
DEFAULT_BUILD_BACKEND = "setuptools.build_meta:__legacy__"
13+
DEFAULT_BUILD_REQUIRES = ("setuptools",)

pex/build_system/pep_517.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@
1010

1111
from pex import third_party
1212
from pex.build_system import DEFAULT_BUILD_BACKEND
13-
from pex.build_system.pep_518 import BuildSystem, load_build_system
13+
from pex.build_system.pep_518 import BuildSystem, load_build_system, load_build_system_table
1414
from pex.common import safe_mkdtemp
1515
from pex.dist_metadata import DistMetadata, Distribution, MetadataType
1616
from pex.jobs import Job, SpawnedJob
17+
from pex.orderedset import OrderedSet
1718
from pex.pip.version import PipVersion, PipVersionValue
1819
from pex.resolve.resolvers import Resolver
1920
from pex.result import Error, try_
@@ -22,7 +23,7 @@
2223
from pex.typing import TYPE_CHECKING, cast
2324

2425
if TYPE_CHECKING:
25-
from typing import Any, Dict, Iterable, List, Mapping, Optional, Set, Text, Union
26+
from typing import Any, Dict, Iterable, List, Mapping, Optional, Set, Text, Tuple, Union
2627

2728
_DEFAULT_BUILD_SYSTEMS = {} # type: Dict[PipVersionValue, BuildSystem]
2829

@@ -248,15 +249,16 @@ def build_sdist(
248249
return os.path.join(dist_dir, sdist_relpath)
249250

250251

251-
def spawn_prepare_metadata(
252+
def get_requires_for_build_wheel(
252253
project_directory, # type: str
253254
target, # type: Target
254255
resolver, # type: Resolver
255256
pip_version=None, # type: Optional[PipVersionValue]
256257
):
257-
# type: (...) -> SpawnedJob[DistMetadata]
258+
# type: (...) -> Tuple[str, ...]
258259

259-
extra_requirements = []
260+
build_system_table = try_(load_build_system_table(project_directory))
261+
requires = OrderedSet(build_system_table.requires)
260262
spawned_job = try_(
261263
_invoke_build_hook(
262264
project_directory,
@@ -267,11 +269,24 @@ def spawn_prepare_metadata(
267269
)
268270
)
269271
try:
270-
extra_requirements.extend(spawned_job.await_result())
272+
requires.update(spawned_job.await_result())
271273
except Job.Error as e:
272274
if e.exitcode != _HOOK_UNAVAILABLE_EXIT_CODE:
273275
raise e
276+
return tuple(requires)
277+
274278

279+
def spawn_prepare_metadata(
280+
project_directory, # type: str
281+
target, # type: Target
282+
resolver, # type: Resolver
283+
pip_version=None, # type: Optional[PipVersionValue]
284+
):
285+
# type: (...) -> SpawnedJob[DistMetadata]
286+
287+
extra_requirements = get_requires_for_build_wheel(
288+
project_directory, target, resolver, pip_version=pip_version
289+
)
275290
build_dir = os.path.join(safe_mkdtemp(), "build")
276291
os.mkdir(build_dir)
277292
spawned_job = try_(

pex/build_system/pep_518.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import subprocess
88

99
from pex import toml
10-
from pex.build_system import DEFAULT_BUILD_BACKEND
10+
from pex.build_system import DEFAULT_BUILD_BACKEND, DEFAULT_BUILD_REQUIRES
1111
from pex.common import REPRODUCIBLE_BUILDS_ENV, CopyMode
1212
from pex.dist_metadata import Distribution
1313
from pex.interpreter import PythonInterpreter
@@ -159,6 +159,25 @@ def create(
159159
env = attr.ib() # type: Mapping[str, str]
160160

161161

162+
def _maybe_load_build_system_table(project_directory):
163+
# type: (str) -> Union[Optional[BuildSystemTable], Error]
164+
165+
# The interface is spec'd here: https://peps.python.org/pep-0518/
166+
pyproject_toml = os.path.join(project_directory, "pyproject.toml")
167+
if not os.path.isfile(pyproject_toml):
168+
return None
169+
return _read_build_system_table(pyproject_toml)
170+
171+
172+
def load_build_system_table(project_directory):
173+
# type: (str) -> Union[BuildSystemTable, Error]
174+
175+
maybe_build_system_table_or_error = _maybe_load_build_system_table(project_directory)
176+
if maybe_build_system_table_or_error is not None:
177+
return maybe_build_system_table_or_error
178+
return BuildSystemTable(requires=DEFAULT_BUILD_REQUIRES, build_backend=DEFAULT_BUILD_BACKEND)
179+
180+
162181
def load_build_system(
163182
target, # type: Target
164183
resolver, # type: Resolver
@@ -167,12 +186,7 @@ def load_build_system(
167186
):
168187
# type: (...) -> Union[Optional[BuildSystem], Error]
169188

170-
# The interface is spec'd here: https://peps.python.org/pep-0518/
171-
pyproject_toml = os.path.join(project_directory, "pyproject.toml")
172-
if not os.path.isfile(pyproject_toml):
173-
return None
174-
175-
maybe_build_system_table_or_error = _read_build_system_table(pyproject_toml)
189+
maybe_build_system_table_or_error = _maybe_load_build_system_table(project_directory)
176190
if not isinstance(maybe_build_system_table_or_error, BuildSystemTable):
177191
return maybe_build_system_table_or_error
178192
build_system_table = maybe_build_system_table_or_error

0 commit comments

Comments
 (0)