Require disambiguated relative paths for --index (#14152)

We do not currently support passing index names to `--index` for
installing packages. However, we do accept relative paths that can look
like index names. This PR adds the requirement that `--index` values
must be disambiguated with a prefix (`./` or `../` on Unix and Windows
or `.\\` or `..\\` on Windows). For now, if an ambiguous value is
provided, uv will warn that this will not be supported in the future.

Currently, if you provide an index name like `--index test` when there
is no `test` directory, uv will error with a `Directory not found...`
error. That's not very informative if you thought index names were
supported. The new warning makes the context clearer.

Closes #13921
This commit is contained in:
John Mumm 2025-06-25 04:02:06 -04:00 committed by GitHub
parent 283323a78a
commit 5b2c3595a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 162 additions and 4 deletions

1
Cargo.lock generated
View file

@ -5177,6 +5177,7 @@ dependencies = [
"uv-pypi-types",
"uv-redacted",
"uv-small-str",
"uv-warnings",
"version-ranges",
]

View file

@ -5130,6 +5130,9 @@ pub struct IndexArgs {
/// All indexes provided via this flag take priority over the index specified by
/// `--default-index` (which defaults to PyPI). When multiple `--index` flags are provided,
/// earlier values take priority.
///
/// Index names are not supported as values. Relative paths must be disambiguated from index
/// names with `./` or `../` on Unix or `.\\`, `..\\`, `./` or `../` on Windows.
//
// The nested Vec structure (`Vec<Vec<Maybe<Index>>>`) is required for clap's
// value parsing mechanism, which processes one value at a time, in order to handle

View file

@ -29,6 +29,7 @@ uv-platform-tags = { workspace = true }
uv-pypi-types = { workspace = true }
uv-redacted = { workspace = true }
uv-small-str = { workspace = true }
uv-warnings = { workspace = true }
arcstr = { workspace = true }
bitflags = { workspace = true }

View file

@ -12,6 +12,7 @@ use url::{ParseError, Url};
use uv_pep508::{Scheme, VerbatimUrl, VerbatimUrlError, split_scheme};
use uv_redacted::DisplaySafeUrl;
use uv_warnings::warn_user;
use crate::{Index, IndexStatusCodeStrategy, Verbatim};
@ -135,6 +136,30 @@ impl IndexUrl {
Cow::Owned(url)
}
}
/// Warn user if the given URL was provided as an ambiguous relative path.
///
/// This is a temporary warning. Ambiguous values will not be
/// accepted in the future.
pub fn warn_on_disambiguated_relative_path(&self) {
let Self::Path(verbatim_url) = &self else {
return;
};
if let Some(path) = verbatim_url.given() {
if !is_disambiguated_path(path) {
if cfg!(windows) {
warn_user!(
"Relative paths passed to `--index` or `--default-index` should be disambiguated from index names (use `.\\{path}` or `./{path}`). Support for ambiguous values will be removed in the future"
);
} else {
warn_user!(
"Relative paths passed to `--index` or `--default-index` should be disambiguated from index names (use `./{path}`). Support for ambiguous values will be removed in the future"
);
}
}
}
}
}
impl Display for IndexUrl {
@ -157,6 +182,28 @@ impl Verbatim for IndexUrl {
}
}
/// Checks if a path is disambiguated.
///
/// Disambiguated paths are absolute paths, paths with valid schemes,
/// and paths starting with "./" or "../" on Unix or ".\\", "..\\",
/// "./", or "../" on Windows.
fn is_disambiguated_path(path: &str) -> bool {
if cfg!(windows) {
if path.starts_with(".\\") || path.starts_with("..\\") || path.starts_with('/') {
return true;
}
}
if path.starts_with("./") || path.starts_with("../") || Path::new(path).is_absolute() {
return true;
}
// Check if the path has a scheme (like `file://`)
if let Some((scheme, _)) = split_scheme(path) {
return Scheme::parse(scheme).is_some();
}
// This is an ambiguous relative path
false
}
/// An error that can occur when parsing an [`IndexUrl`].
#[derive(Error, Debug)]
pub enum IndexUrlError {
@ -620,3 +667,41 @@ impl IndexCapabilities {
.insert(Flags::FORBIDDEN);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_index_url_parse_valid_paths() {
// Absolute path
assert!(is_disambiguated_path("/absolute/path"));
// Relative path
assert!(is_disambiguated_path("./relative/path"));
assert!(is_disambiguated_path("../../relative/path"));
if cfg!(windows) {
// Windows absolute path
assert!(is_disambiguated_path("C:/absolute/path"));
// Windows relative path
assert!(is_disambiguated_path(".\\relative\\path"));
assert!(is_disambiguated_path("..\\..\\relative\\path"));
}
}
#[test]
fn test_index_url_parse_ambiguous_paths() {
// Test single-segment ambiguous path
assert!(!is_disambiguated_path("index"));
// Test multi-segment ambiguous path
assert!(!is_disambiguated_path("relative/path"));
}
#[test]
fn test_index_url_parse_with_schemes() {
assert!(is_disambiguated_path("file:///absolute/path"));
assert!(is_disambiguated_path("https://registry.com/simple/"));
assert!(is_disambiguated_path(
"git+https://github.com/example/repo.git"
));
}
}

View file

@ -1386,6 +1386,12 @@ impl AddSettings {
)
.collect::<Vec<_>>();
// Warn user if an ambiguous relative path was passed as a value for
// `--index` or `--default-index`.
indexes
.iter()
.for_each(|index| index.url().warn_on_disambiguated_relative_path());
// If the user passed an `--index-url` or `--extra-index-url`, warn.
if installer
.index_args

View file

@ -9446,7 +9446,7 @@ fn add_index_with_existing_relative_path_index() -> Result<()> {
let wheel_dst = packages.child("ok-1.0.0-py3-none-any.whl");
fs_err::copy(&wheel_src, &wheel_dst)?;
uv_snapshot!(context.filters(), context.add().arg("iniconfig").arg("--index").arg("test-index"), @r"
uv_snapshot!(context.filters(), context.add().arg("iniconfig").arg("--index").arg("./test-index"), @r"
success: true
exit_code: 0
----- stdout -----
@ -9475,7 +9475,7 @@ fn add_index_with_non_existent_relative_path() -> Result<()> {
dependencies = []
"#})?;
uv_snapshot!(context.filters(), context.add().arg("iniconfig").arg("--index").arg("test-index"), @r"
uv_snapshot!(context.filters(), context.add().arg("iniconfig").arg("--index").arg("./test-index"), @r"
success: false
exit_code: 2
----- stdout -----
@ -9505,7 +9505,7 @@ fn add_index_with_non_existent_relative_path_with_same_name_as_index() -> Result
url = "https://pypi-proxy.fly.dev/simple"
"#})?;
uv_snapshot!(context.filters(), context.add().arg("iniconfig").arg("--index").arg("test-index"), @r"
uv_snapshot!(context.filters(), context.add().arg("iniconfig").arg("--index").arg("./test-index"), @r"
success: false
exit_code: 2
----- stdout -----
@ -9528,12 +9528,16 @@ fn add_index_empty_directory() -> Result<()> {
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []
[[tool.uv.index]]
name = "test-index"
url = "https://pypi-proxy.fly.dev/simple"
"#})?;
let packages = context.temp_dir.child("test-index");
packages.create_dir_all()?;
uv_snapshot!(context.filters(), context.add().arg("iniconfig").arg("--index").arg("test-index"), @r"
uv_snapshot!(context.filters(), context.add().arg("iniconfig").arg("--index").arg("./test-index"), @r"
success: true
exit_code: 0
----- stdout -----
@ -9549,6 +9553,46 @@ fn add_index_empty_directory() -> Result<()> {
Ok(())
}
#[test]
fn add_index_with_ambiguous_relative_path() -> Result<()> {
let context = TestContext::new("3.12");
let mut filters = context.filters();
filters.push((r"\./|\.\\\\", r"[PREFIX]"));
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(indoc! {r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = []
"#})?;
#[cfg(unix)]
uv_snapshot!(filters, context.add().arg("iniconfig").arg("--index").arg("test-index"), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
warning: Relative paths passed to `--index` or `--default-index` should be disambiguated from index names (use `[PREFIX]test-index`). Support for ambiguous values will be removed in the future
error: Directory not found for index: file://[TEMP_DIR]/test-index
");
#[cfg(windows)]
uv_snapshot!(filters, context.add().arg("iniconfig").arg("--index").arg("test-index"), @r"
success: false
exit_code: 2
----- stdout -----
----- stderr -----
warning: Relative paths passed to `--index` or `--default-index` should be disambiguated from index names (use `[PREFIX]test-index` or `[PREFIX]test-index`). Support for ambiguous values will be removed in the future
error: Directory not found for index: file://[TEMP_DIR]/test-index
");
Ok(())
}
/// Add a PyPI requirement.
#[test]
fn add_group_comment() -> Result<()> {

View file

@ -123,6 +123,7 @@ uv run [OPTIONS] [COMMAND]
</dd><dt id="uv-run--index"><a href="#uv-run--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-run--index-strategy"><a href="#uv-run--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -479,6 +480,7 @@ uv add [OPTIONS] <PACKAGES|--requirements <REQUIREMENTS>>
</dd><dt id="uv-add--index"><a href="#uv-add--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-add--index-strategy"><a href="#uv-add--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -663,6 +665,7 @@ uv remove [OPTIONS] <PACKAGES>...
</dd><dt id="uv-remove--index"><a href="#uv-remove--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-remove--index-strategy"><a href="#uv-remove--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -832,6 +835,7 @@ uv version [OPTIONS] [VALUE]
</dd><dt id="uv-version--index"><a href="#uv-version--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-version--index-strategy"><a href="#uv-version--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -1022,6 +1026,7 @@ uv sync [OPTIONS]
</dd><dt id="uv-sync--index"><a href="#uv-sync--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-sync--index-strategy"><a href="#uv-sync--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -1210,6 +1215,7 @@ uv lock [OPTIONS]
</dd><dt id="uv-lock--index"><a href="#uv-lock--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-lock--index-strategy"><a href="#uv-lock--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -1383,6 +1389,7 @@ uv export [OPTIONS]
</dd><dt id="uv-export--index"><a href="#uv-export--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-export--index-strategy"><a href="#uv-export--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -1568,6 +1575,7 @@ uv tree [OPTIONS]
</dd><dt id="uv-tree--index"><a href="#uv-tree--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-tree--index-strategy"><a href="#uv-tree--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -1827,6 +1835,7 @@ uv tool run [OPTIONS] [COMMAND]
</dd><dt id="uv-tool-run--index"><a href="#uv-tool-run--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-tool-run--index-strategy"><a href="#uv-tool-run--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -1997,6 +2006,7 @@ uv tool install [OPTIONS] <PACKAGE>
</dd><dt id="uv-tool-install--index"><a href="#uv-tool-install--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-tool-install--index-strategy"><a href="#uv-tool-install--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -2157,6 +2167,7 @@ uv tool upgrade [OPTIONS] <NAME>...
</dd><dt id="uv-tool-upgrade--index"><a href="#uv-tool-upgrade--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-tool-upgrade--index-strategy"><a href="#uv-tool-upgrade--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -3252,6 +3263,7 @@ uv pip compile [OPTIONS] <SRC_FILE|--group <GROUP>>
</dd><dt id="uv-pip-compile--index"><a href="#uv-pip-compile--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-pip-compile--index-strategy"><a href="#uv-pip-compile--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -3531,6 +3543,7 @@ uv pip sync [OPTIONS] <SRC_FILE>...
</dd><dt id="uv-pip-sync--index"><a href="#uv-pip-sync--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-pip-sync--index-strategy"><a href="#uv-pip-sync--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -3795,6 +3808,7 @@ uv pip install [OPTIONS] <PACKAGE|--requirements <REQUIREMENTS>|--editable <EDIT
</dd><dt id="uv-pip-install--index"><a href="#uv-pip-install--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-pip-install--index-strategy"><a href="#uv-pip-install--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -4214,6 +4228,7 @@ uv pip list [OPTIONS]
</dd><dt id="uv-pip-list--index"><a href="#uv-pip-list--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-pip-list--index-strategy"><a href="#uv-pip-list--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -4387,6 +4402,7 @@ uv pip tree [OPTIONS]
</dd><dt id="uv-pip-tree--index"><a href="#uv-pip-tree--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-pip-tree--index-strategy"><a href="#uv-pip-tree--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -4574,6 +4590,7 @@ uv venv [OPTIONS] [PATH]
</dd><dt id="uv-venv--index"><a href="#uv-venv--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-venv--index-strategy"><a href="#uv-venv--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>
@ -4724,6 +4741,7 @@ uv build [OPTIONS] [SRC]
</dd><dt id="uv-build--index"><a href="#uv-build--index"><code>--index</code></a> <i>index</i></dt><dd><p>The URLs to use when resolving dependencies, in addition to the default index.</p>
<p>Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.</p>
<p>All indexes provided via this flag take priority over the index specified by <code>--default-index</code> (which defaults to PyPI). When multiple <code>--index</code> flags are provided, earlier values take priority.</p>
<p>Index names are not supported as values. Relative paths must be disambiguated from index names with <code>./</code> or <code>../</code> on Unix or <code>.\\</code>, <code>..\\</code>, <code>./</code> or <code>../</code> on Windows.</p>
<p>May also be set with the <code>UV_INDEX</code> environment variable.</p></dd><dt id="uv-build--index-strategy"><a href="#uv-build--index-strategy"><code>--index-strategy</code></a> <i>index-strategy</i></dt><dd><p>The strategy to use when resolving against multiple index URLs.</p>
<p>By default, uv will stop at the first index on which a given package is available, and limit resolutions to those present on that first index (<code>first-index</code>). This prevents &quot;dependency confusion&quot; attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.</p>
<p>May also be set with the <code>UV_INDEX_STRATEGY</code> environment variable.</p><p>Possible values:</p>