diff --git a/piptools/scripts/compile.py b/piptools/scripts/compile.py index 9518403f4..7fd0edfbe 100755 --- a/piptools/scripts/compile.py +++ b/piptools/scripts/compile.py @@ -12,6 +12,7 @@ import click import pyproject_hooks from build import BuildBackendException, ProjectBuilder +from build.env import IsolatedEnvBuilder from build.util import project_wheel_metadata from click.utils import LazyFile, safecall from pip._internal.commands import create_command @@ -53,18 +54,24 @@ def _build_requirements( src_dir: str, src_file: str, distributions: Iterable[str], package_name: str ) -> list[InstallRequirement]: - builder = ProjectBuilder(src_dir, runner=pyproject_hooks.quiet_subprocess_runner) - # It is not clear that it should be possible to use `get_requires_for_build` with - # "editable" but it seems to work in practice. result = collections.defaultdict(set) - for req in builder.build_system_requires: - result[req].add(f"{package_name} ({src_file}::build-system.requires)") - # TODO: Follow PEP and install deps - for dist in distributions: - for req in builder.get_requires_for_build(dist): - result[req].add( - f"{package_name} ({src_file}::build-system.backend::{dist})" - ) + + with IsolatedEnvBuilder() as env: + builder = ProjectBuilder( + srcdir=src_dir, + python_executable=env.executable, + scripts_dir=env.scripts_dir, + runner=pyproject_hooks.quiet_subprocess_runner, + ) + env.install(builder.build_system_requires) + + for req in builder.build_system_requires: + result[req].add(f"{package_name} ({src_file}::build-system.requires)") + for dist in distributions: + for req in builder.get_requires_for_build(dist): + result[req].add( + f"{package_name} ({src_file}::build-system.backend::{dist})" + ) return [ install_req_from_line(k, comes_from=v) for k, vs in result.items() for v in vs diff --git a/tests/conftest.py b/tests/conftest.py index 8fee4ca1e..fdd192184 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -319,6 +319,7 @@ def _make_package(name, version="0.1", install_requires=None, extras_require=Non url="https://github.com/jazzband/pip-tools", install_requires={install_requires_str}, extras_require={extras_require}, + py_modules=[{name!r}], ) """ ) @@ -327,6 +328,9 @@ def _make_package(name, version="0.1", install_requires=None, extras_require=Non # Create a README to avoid setuptools warnings. (package_dir / "README").touch() + # Create a module to make the package importable. + (package_dir / name).with_suffix(".py").touch() + return package_dir return _make_package diff --git a/tests/test_data/packages/small_fake_with_build_deps/backend/backend.py b/tests/test_data/packages/small_fake_with_build_deps/backend/backend.py index d44130334..41a9bea31 100644 --- a/tests/test_data/packages/small_fake_with_build_deps/backend/backend.py +++ b/tests/test_data/packages/small_fake_with_build_deps/backend/backend.py @@ -1,15 +1,13 @@ from __future__ import annotations +# A dependency of the build backend that is not installed is equivalent to a build +# backend that is not installed so we don't have to test both cases. +import fake_static_build_dep import setuptools.build_meta # Re-export all names in case more hooks are added in the future from setuptools.build_meta import * # noqa: F401, F403 -# FIXME: install static build deps somehow -# Here the backend imports another dep but the same problem applies if the backend -# itself is not installed in the environment where pip-compile runs. -# import fake_static_build_dep - build_wheel = setuptools.build_meta.build_wheel build_sdist = setuptools.build_meta.build_sdist