mirror of https://github.com/astral-sh/uv
Allow per dependency build isolation for setup.py projects as well (#6517)
<!--
Thank you for contributing to uv! To help us out with reviewing, please
consider the following:
- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->
## Summary
<!-- What's the purpose of the change? What does it do, and why? -->
This changes the behavior a bit of the per-dependency build-isolation
override. That, if the dist name is known, it is passed into the
`SourceBuild::Setup` function. This allows for this override to work for
projects without a `pyproject.toml`, like `detectron2`, using the
specified requirement name. Previously only the `pyproject.toml` name
could be used, which these projects are lacking. An example of a
use-case is given in the *Test Plan* section.
Additionally, the `no_build_isolation_package` has been adding to
`InstallerSettingsRef` and used in `sync` and other commands, as this
was not done yet.
This is useful if you want to **non**-isolate a single package, even
ones without a proper `pyproject.toml`
## Test Plan
<!-- How was it tested? -->
With the following pyproject.toml.
```toml
[project]
name = "detectron-uv"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"detectron2",
"setuptools",
"torch",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.uv.sources]
detectron2 = { git = "https://github.com/facebookresearch/detectron2", rev = "bcfd464d0c810f0442d91a349c0f6df945467143" }
[tool.uv]
no-build-isolation-package = ["detectron2"]
```
The package `detectron2` is now correctly **non**-isolated. Before,
because the logic depended on getting the name from the
`pyproject.toml`, which is lacking in detectron2 you would get the
message, that the source could not be built. This was because it would
still be *isolated* in that case.
With these changes you can now install using (given that you are inside
a workspace with a venv):
```
uv pip install torch setuptools
uv sync
```
This would previously fail with something like:
```
error: Failed to prepare distributions
Caused by: Failed to fetch wheel: detectron2 @ git+https://github.com/facebookresearch/detectron2@bcfd464d0c810f0442d91a349c0f6df945467143
Caused by: Build backend failed to determine extra requires with `build_wheel()` with exit status: 1
--- stdout:
--- stderr:
Traceback (most recent call last):
File "<string>", line 14, in <module>
File "/Users/tdejager/Library/Caches/uv/builds-v0/.tmptloDcZ/lib/python3.12/site-packages/setuptools/build_meta.py", line 332, in get_requires_for_build_wheel
return self._get_build_requires(config_settings, requirements=[])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/tdejager/Library/Caches/uv/builds-v0/.tmptloDcZ/lib/python3.12/site-packages/setuptools/build_meta.py", line 302, in _get_build_requires
self.run_setup()
File "/Users/tdejager/Library/Caches/uv/builds-v0/.tmptloDcZ/lib/python3.12/site-packages/setuptools/build_meta.py", line 502, in run_setup
super().run_setup(setup_script=setup_script)
File "/Users/tdejager/Library/Caches/uv/builds-v0/.tmptloDcZ/lib/python3.12/site-packages/setuptools/build_meta.py", line 318, in run_setup
exec(code, locals())
File "<string>", line 10, in <module>
ModuleNotFoundError: No module named 'torch'
---
Caused by: This error likely indicates that detectron2 @ git+https://github.com/facebookresearch/detectron2@bcfd464d0c810f0442d91a349c0f6df945467143 depends on torch, but doesn't declare it as a build dependency. If detectron2 @ git+https://github.com/facebookresearch/detectron2@bcfd464d0c810f0442d91a349c0f6df945467143 is a first-party package, consider adding torch to its `build-system.requires`. Otherwise, `uv pip install torch` into the environment and re-run with `--no-build-isolation`.
```
**Edit**:
Some wording, used isolated where it should be **non**-isolated.
This commit is contained in:
parent
b68406bb56
commit
50997bcb41
|
|
@ -398,6 +398,7 @@ impl SourceBuild {
|
|||
pub async fn setup(
|
||||
source: &Path,
|
||||
subdirectory: Option<&Path>,
|
||||
fallback_package_name: Option<&PackageName>,
|
||||
interpreter: &Interpreter,
|
||||
build_context: &impl BuildContext,
|
||||
source_build_context: SourceBuildContext,
|
||||
|
|
@ -422,10 +423,10 @@ impl SourceBuild {
|
|||
let (pep517_backend, project) =
|
||||
Self::extract_pep517_backend(&source_tree, &default_backend).map_err(|err| *err)?;
|
||||
|
||||
let package_name = project.clone().map(|p| p.name);
|
||||
let package_name = project.as_ref().map(|p| &p.name).or(fallback_package_name);
|
||||
|
||||
// Create a virtual environment, or install into the shared environment if requested.
|
||||
let venv = if let Some(venv) = build_isolation.shared_environment(package_name.as_ref()) {
|
||||
let venv = if let Some(venv) = build_isolation.shared_environment(package_name) {
|
||||
venv.clone()
|
||||
} else {
|
||||
uv_virtualenv::create_venv(
|
||||
|
|
@ -440,7 +441,7 @@ impl SourceBuild {
|
|||
|
||||
// Setup the build environment. If build isolation is disabled, we assume the build
|
||||
// environment is already setup.
|
||||
if build_isolation.is_isolated(package_name.as_ref()) {
|
||||
if build_isolation.is_isolated(package_name) {
|
||||
let resolved_requirements = Self::get_resolved_requirements(
|
||||
build_context,
|
||||
source_build_context,
|
||||
|
|
@ -490,7 +491,7 @@ impl SourceBuild {
|
|||
// Create the PEP 517 build environment. If build isolation is disabled, we assume the build
|
||||
// environment is already setup.
|
||||
let runner = PythonRunner::new(concurrent_builds);
|
||||
if build_isolation.is_isolated(package_name.as_ref()) {
|
||||
if build_isolation.is_isolated(package_name) {
|
||||
create_pep517_build_environment(
|
||||
&runner,
|
||||
&source_tree,
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ pub(crate) async fn build(args: BuildArgs) -> Result<PathBuf> {
|
|||
let builder = SourceBuild::setup(
|
||||
&args.sdist,
|
||||
args.subdirectory.as_deref(),
|
||||
None,
|
||||
python.interpreter(),
|
||||
&build_dispatch,
|
||||
SourceBuildContext::default(),
|
||||
|
|
|
|||
|
|
@ -298,11 +298,12 @@ impl<'a> BuildContext for BuildDispatch<'a> {
|
|||
dist: Option<&'data SourceDist>,
|
||||
build_kind: BuildKind,
|
||||
) -> Result<SourceBuild> {
|
||||
let dist_name = dist.map(distribution_types::Name::name);
|
||||
// Note we can only prevent builds by name for packages with names
|
||||
// unless all builds are disabled.
|
||||
if self
|
||||
.build_options
|
||||
.no_build_requirement(dist.map(distribution_types::Name::name))
|
||||
.no_build_requirement(dist_name)
|
||||
// We always allow editable builds
|
||||
&& !matches!(build_kind, BuildKind::Editable)
|
||||
{
|
||||
|
|
@ -318,6 +319,7 @@ impl<'a> BuildContext for BuildDispatch<'a> {
|
|||
let builder = SourceBuild::setup(
|
||||
source,
|
||||
subdirectory,
|
||||
dist_name,
|
||||
self.interpreter,
|
||||
self,
|
||||
self.source_build_context.clone(),
|
||||
|
|
|
|||
Loading…
Reference in New Issue