-
Notifications
You must be signed in to change notification settings - Fork 2.9k
project sources shadow workspace sources, even when disabled by markers #14093
Description
Summary
Here's a minimal repro. pyproject.toml at the root of the workspace:
[tool.uv.workspace]
members = ["foo"]
[[tool.uv.sources.numpy]]
path = "/var/tmp/numpy-2.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"And foo/pyproject.toml:
[project]
name = "foo"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = ["numpy"]
[[tool.uv.sources.numpy]]
path = "/var/tmp/numpy-2.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
marker = "sys_platform == 'foobarbaz'"So what we have is both a workspace-level and a project-level source for numpy. However, the project-level source is disabled by a marker that will never be true. Here's what I see when I uv sync:
$ rm -r .venv && uv sync
Using CPython 3.13.2
Creating virtual environment at: .venv
Resolved 3 packages in 60ms
Installed 1 package in 11ms
+ numpy==2.2.0
Contrast that with what I see if I remove the project-level source:
$ rm -r .venv && uv sync
Using CPython 3.13.2
Creating virtual environment at: .venv
Resolved 2 packages in 0.65ms
Installed 1 package in 11ms
+ numpy==2.2.0 (from file:///var/tmp/numpy-2.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl)
In this case the workspace-level source is used. The bug(?) is that it should've been used in both cases. I think the cause is structure of the following if statement:
uv/crates/uv-distribution/src/metadata/lowering.rs
Lines 49 to 55 in cf67d9c
| let (sources, origin) = if let Some(source) = project_sources.get(&requirement.name) { | |
| (Some(source), RequirementOrigin::Project) | |
| } else if let Some(source) = workspace.sources().get(&requirement.name) { | |
| (Some(source), RequirementOrigin::Workspace) | |
| } else { | |
| (None, RequirementOrigin::Project) | |
| }; |
In that code, if there's a project-level source with a matching name, then any workspace-level source is ignored. But this happens before markers are checked.
Platform
linux
Version
uv 0.7.13 (62ed17b 2025-06-12)
Python version
No response