diff --git a/crates/distribution-types/src/index_source.rs b/crates/distribution-types/src/index.rs similarity index 93% rename from crates/distribution-types/src/index_source.rs rename to crates/distribution-types/src/index.rs index 9c3da94f89197..9a0ac31e95dc1 100644 --- a/crates/distribution-types/src/index_source.rs +++ b/crates/distribution-types/src/index.rs @@ -5,7 +5,7 @@ use crate::{IndexUrl, IndexUrlError}; #[derive(Debug, Clone, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] -pub struct IndexSource { +pub struct Index { /// The name of the index. /// /// Index names can be used to reference indexes elsewhere in the configuration. For example, @@ -72,8 +72,8 @@ pub struct IndexSource { // Flat, // } -impl IndexSource { - /// Initialize an [`IndexSource`] from a pip-style `--index-url`. +impl Index { + /// Initialize an [`Index`] from a pip-style `--index-url`. pub fn from_index_url(url: IndexUrl) -> Self { Self { url, @@ -83,7 +83,7 @@ impl IndexSource { } } - /// Initialize an [`IndexSource`] from a pip-style `--extra-index-url`. + /// Initialize an [`Index`] from a pip-style `--extra-index-url`. pub fn from_extra_index_url(url: IndexUrl) -> Self { Self { url, @@ -94,7 +94,7 @@ impl IndexSource { } } -impl FromStr for IndexSource { +impl FromStr for Index { type Err = IndexSourceError; fn from_str(s: &str) -> Result { @@ -126,7 +126,7 @@ impl FromStr for IndexSource { } } -/// An error that can occur when parsing an [`IndexSource`]. +/// An error that can occur when parsing an [`Index`]. #[derive(Error, Debug)] pub enum IndexSourceError { #[error(transparent)] diff --git a/crates/distribution-types/src/index_url.rs b/crates/distribution-types/src/index_url.rs index cd7749a1238b7..0a7ae16ff94ae 100644 --- a/crates/distribution-types/src/index_url.rs +++ b/crates/distribution-types/src/index_url.rs @@ -11,7 +11,7 @@ use url::{ParseError, Url}; use pep508_rs::{VerbatimUrl, VerbatimUrlError}; -use crate::{IndexSource, Verbatim}; +use crate::{Index, Verbatim}; static PYPI_URL: LazyLock = LazyLock::new(|| Url::parse("https://pypi.org/simple").unwrap()); @@ -55,6 +55,7 @@ impl IndexUrl { } } + /// Convert the index URL into a [`Url`]. pub fn into_url(self) -> Url { match self { Self::Pypi(url) => url.into_url(), @@ -300,18 +301,14 @@ impl From for FlatIndexLocation { #[derive(Default, Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[serde(rename_all = "kebab-case", deny_unknown_fields)] pub struct IndexLocations { - indexes: Vec, + indexes: Vec, flat_index: Vec, no_index: bool, } impl IndexLocations { /// Determine the index URLs to use for fetching packages. - pub fn new( - indexes: Vec, - flat_index: Vec, - no_index: bool, - ) -> Self { + pub fn new(indexes: Vec, flat_index: Vec, no_index: bool) -> Self { Self { indexes, flat_index, @@ -328,7 +325,7 @@ impl IndexLocations { #[must_use] pub fn combine( self, - indexes: Vec, + indexes: Vec, flat_index: Vec, no_index: bool, ) -> Self { @@ -425,7 +422,7 @@ impl<'a> IndexLocations { /// From a pip perspective, this type merges `--index-url` and `--extra-index-url`. #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct IndexUrls { - indexes: Vec, + indexes: Vec, no_index: bool, } diff --git a/crates/distribution-types/src/lib.rs b/crates/distribution-types/src/lib.rs index 0d7c07cf716ba..c5f3abddcd1c9 100644 --- a/crates/distribution-types/src/lib.rs +++ b/crates/distribution-types/src/lib.rs @@ -57,7 +57,7 @@ pub use crate::error::*; pub use crate::file::*; pub use crate::hash::*; pub use crate::id::*; -pub use crate::index_source::*; +pub use crate::index::*; pub use crate::index_url::*; pub use crate::installed::*; pub use crate::prioritized_distribution::*; @@ -76,7 +76,7 @@ mod error; mod file; mod hash; mod id; -mod index_source; +mod index; mod index_url; mod installed; mod prioritized_distribution; diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index 2afd40a50f42c..636d1aa8de788 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -7,7 +7,7 @@ use anyhow::{anyhow, Result}; use clap::builder::styling::{AnsiColor, Effects, Style}; use clap::builder::Styles; use clap::{Args, Parser, Subcommand}; -use distribution_types::{FlatIndexLocation, IndexSource, IndexUrl}; +use distribution_types::{FlatIndexLocation, Index, IndexUrl}; use pep508_rs::Requirement; use pypi_types::VerbatimParsedUrl; use url::Url; @@ -779,13 +779,13 @@ fn parse_index_url(input: &str) -> Result, String> { } } -/// Parse a string into an [`IndexSource`], mapping the empty string to `None`. -fn parse_index_source(input: &str) -> Result, String> { +/// Parse a string into an [`Index`], mapping the empty string to `None`. +fn parse_index_source(input: &str) -> Result, String> { if input.is_empty() { Ok(Maybe::None) } else { - match IndexSource::from_str(input) { - Ok(index) => Ok(Maybe::Some(IndexSource { + match Index::from_str(input) { + Ok(index) => Ok(Maybe::Some(Index { default: false, ..index })), @@ -794,13 +794,13 @@ fn parse_index_source(input: &str) -> Result, String> { } } -/// Parse a string into an [`IndexSource`], mapping the empty string to `None`. -fn parse_default_index_source(input: &str) -> Result, String> { +/// Parse a string into an [`Index`], mapping the empty string to `None`. +fn parse_default_index_source(input: &str) -> Result, String> { if input.is_empty() { Ok(Maybe::None) } else { - match IndexSource::from_str(input) { - Ok(index) => Ok(Maybe::Some(IndexSource { + match Index::from_str(input) { + Ok(index) => Ok(Maybe::Some(Index { default: true, ..index })), @@ -2266,8 +2266,8 @@ pub struct VenvArgs { /// /// 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 (`first-match`). This prevents - /// "dependency confusion" attacks, whereby an attack can upload a malicious package under the - /// same name to a secondary. + /// "dependency confusion" attacks, whereby an attacker can upload a malicious package under the + /// same name to an alternate index. #[arg(long, value_enum, env = "UV_INDEX_STRATEGY")] pub index_strategy: Option, @@ -3718,7 +3718,7 @@ pub struct GenerateShellCompletionArgs { #[derive(Args)] #[allow(clippy::struct_excessive_bools)] pub struct IndexArgs { - /// The URLs of packages indexes to use when resolving dependencies. + /// The URLs to use when resolving dependencies, in addition to the default index. /// /// Accepts either a repository compliant with PEP 503 (the simple repository API), or a local /// directory laid out in the same format. @@ -3727,7 +3727,7 @@ pub struct IndexArgs { /// `--default-index` (which defaults to PyPI). When multiple `--index` flags are /// provided, earlier values take priority. #[arg(long, env = "UV_INDEX", value_delimiter = ' ', value_parser = parse_index_source, help_heading = "Index options")] - pub index: Option>>, + pub index: Option>>, /// The URL of the default package index (by default: ). /// @@ -3737,7 +3737,7 @@ pub struct IndexArgs { /// The index given by this flag is given lower priority than all other indexes specified via /// the `--index` flag. #[arg(long, env = "UV_DEFAULT_INDEX", value_parser = parse_default_index_source, help_heading = "Index options")] - pub default_index: Option>, + pub default_index: Option>, /// The URL of the Python package index (by default: ). /// @@ -3884,8 +3884,8 @@ pub struct InstallerArgs { /// /// 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 (`first-match`). This prevents - /// "dependency confusion" attacks, whereby an attack can upload a malicious package under the - /// same name to a secondary. + /// "dependency confusion" attacks, whereby an attacker can upload a malicious package under the + /// same name to an alternate index. #[arg( long, value_enum, @@ -4046,8 +4046,8 @@ pub struct ResolverArgs { /// /// 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 (`first-match`). This prevents - /// "dependency confusion" attacks, whereby an attack can upload a malicious package under the - /// same name to a secondary. + /// "dependency confusion" attacks, whereby an attacker can upload a malicious package under the + /// same name to an alternate index. #[arg( long, value_enum, @@ -4238,8 +4238,8 @@ pub struct ResolverInstallerArgs { /// /// 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 (`first-match`). This prevents - /// "dependency confusion" attacks, whereby an attack can upload a malicious package under the - /// same name to a secondary. + /// "dependency confusion" attacks, whereby an attacker can upload a malicious package under the + /// same name to an alternate index. #[arg( long, value_enum, diff --git a/crates/uv-distribution/src/metadata/lowering.rs b/crates/uv-distribution/src/metadata/lowering.rs index ecbfc3eec2e4a..4d7fa401ea676 100644 --- a/crates/uv-distribution/src/metadata/lowering.rs +++ b/crates/uv-distribution/src/metadata/lowering.rs @@ -6,7 +6,7 @@ use thiserror::Error; use url::Url; use distribution_filename::DistExtension; -use distribution_types::IndexSource; +use distribution_types::Index; use pep440_rs::VersionSpecifiers; use pep508_rs::{VerbatimUrl, VersionOrUrl}; use pypi_types::{ParsedUrlError, Requirement, RequirementSource, VerbatimParsedUrl}; @@ -34,7 +34,7 @@ impl LoweredRequirement { project_name: &PackageName, project_dir: &Path, project_sources: &BTreeMap, - project_indexes: &[IndexSource], + project_indexes: &[Index], workspace: &Workspace, ) -> Result { let (source, origin) = if let Some(source) = project_sources.get(&requirement.name) { @@ -115,15 +115,13 @@ impl LoweredRequirement { // in that order. let Some(index) = project_indexes .iter() - .find(|IndexSource { name, .. }| { - name.as_ref().is_some_and(|name| *name == index) - }) + .find(|Index { name, .. }| name.as_ref().is_some_and(|name| *name == index)) .or_else(|| { - workspace.indexes().iter().find(|IndexSource { name, .. }| { + workspace.indexes().iter().find(|Index { name, .. }| { name.as_ref().is_some_and(|name| *name == index) }) }) - .map(|IndexSource { url: index, .. }| index.clone()) + .map(|Index { url: index, .. }| index.clone()) else { return Err(LoweringError::MissingIndex(requirement.name, index)); }; @@ -205,7 +203,7 @@ impl LoweredRequirement { requirement: pep508_rs::Requirement, dir: &Path, sources: &BTreeMap, - indexes: &[IndexSource], + indexes: &[Index], ) -> Result { let source = sources.get(&requirement.name).cloned(); @@ -247,10 +245,8 @@ impl LoweredRequirement { Source::Registry { index } => { let Some(index) = indexes .iter() - .find(|IndexSource { name, .. }| { - name.as_ref().is_some_and(|name| *name == index) - }) - .map(|IndexSource { url: index, .. }| index.clone()) + .find(|Index { name, .. }| name.as_ref().is_some_and(|name| *name == index)) + .map(|Index { url: index, .. }| index.clone()) else { return Err(LoweringError::MissingIndex(requirement.name, index)); }; diff --git a/crates/uv-scripts/src/lib.rs b/crates/uv-scripts/src/lib.rs index 537ef1cbc9980..2ca7fd4773eb6 100644 --- a/crates/uv-scripts/src/lib.rs +++ b/crates/uv-scripts/src/lib.rs @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::LazyLock; -use distribution_types::IndexSource; +use distribution_types::Index; use memchr::memmem::Finder; use pep440_rs::VersionSpecifiers; use pep508_rs::PackageName; @@ -194,7 +194,7 @@ pub struct ToolUv { #[serde(flatten)] pub top_level: ResolverInstallerOptions, pub sources: Option>, - pub indexes: Option>, + pub indexes: Option>, } #[derive(Debug, Error)] diff --git a/crates/uv-settings/src/settings.rs b/crates/uv-settings/src/settings.rs index 5cbbf80c97e26..2881b840f3ac4 100644 --- a/crates/uv-settings/src/settings.rs +++ b/crates/uv-settings/src/settings.rs @@ -1,6 +1,6 @@ use std::{fmt::Debug, num::NonZeroUsize, path::PathBuf}; -use distribution_types::{FlatIndexLocation, IndexSource, IndexUrl, StaticMetadata}; +use distribution_types::{FlatIndexLocation, Index, IndexUrl, StaticMetadata}; use install_wheel_rs::linker::LinkMode; use pep508_rs::Requirement; use pypi_types::{SupportedEnvironments, VerbatimParsedUrl}; @@ -234,7 +234,7 @@ pub struct GlobalOptions { #[serde(rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct InstallerOptions { - pub index: Option>, + pub index: Option>, pub index_url: Option, pub extra_index_url: Option>, pub no_index: Option, @@ -262,7 +262,7 @@ pub struct InstallerOptions { #[serde(rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct ResolverOptions { - pub index: Option>, + pub index: Option>, pub index_url: Option, pub extra_index_url: Option>, pub no_index: Option, @@ -329,7 +329,7 @@ pub struct ResolverInstallerOptions { url = "https://download.pytorch.org/whl/cu121" "# )] - pub index: Option>, + pub index: Option>, /// The URL of the Python package index (by default: ). /// /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/) @@ -398,8 +398,8 @@ pub struct ResolverInstallerOptions { /// /// 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 (`first-match`). This prevents - /// "dependency confusion" attacks, whereby an attack can upload a malicious package under the - /// same name to a secondary. + /// "dependency confusion" attacks, whereby an attacker can upload a malicious package under the + /// same name to an alternate index. #[option( default = "\"first-index\"", value_type = "str", @@ -773,7 +773,7 @@ pub struct PipOptions { /// Additionally, marking an index as default will disable the PyPI default index. #[serde(skip)] #[cfg_attr(feature = "schemars", schemars(skip))] - pub index: Option>, + pub index: Option>, /// The URL of the Python package index (by default: ). /// /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/) @@ -837,8 +837,8 @@ pub struct PipOptions { /// /// 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 (`first-match`). This prevents - /// "dependency confusion" attacks, whereby an attack can upload a malicious package under the - /// same name to a secondary. + /// "dependency confusion" attacks, whereby an attacker can upload a malicious package under the + /// same name to an alternate index. #[option( default = "\"first-index\"", value_type = "str", @@ -1444,7 +1444,7 @@ impl From for InstallerOptions { #[serde(deny_unknown_fields, rename_all = "kebab-case")] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct ToolOptions { - pub index: Option>, + pub index: Option>, pub index_url: Option, pub extra_index_url: Option>, pub no_index: Option, @@ -1550,7 +1550,7 @@ pub struct OptionsWire { // #[serde(flatten)] // top_level: ResolverInstallerOptions, - index: Option>, + index: Option>, index_url: Option, extra_index_url: Option>, no_index: Option, diff --git a/crates/uv-workspace/src/pyproject.rs b/crates/uv-workspace/src/pyproject.rs index 3ce3a92e9b9af..724f50dc668c5 100644 --- a/crates/uv-workspace/src/pyproject.rs +++ b/crates/uv-workspace/src/pyproject.rs @@ -6,7 +6,7 @@ //! //! Then lowers them into a dependency specification. -use distribution_types::IndexSource; +use distribution_types::Index; use glob::Pattern; use pep440_rs::{Version, VersionSpecifiers}; use pypi_types::{RequirementSource, SupportedEnvironments, VerbatimParsedUrl}; @@ -189,7 +189,7 @@ pub struct ToolUv { url = "https://download.pytorch.org/whl/cu121" "# )] - pub index: Option>, + pub index: Option>, /// The workspace definition for the project, if any. #[option_group] diff --git a/crates/uv-workspace/src/workspace.rs b/crates/uv-workspace/src/workspace.rs index abbadc12abfa9..0f15ea3129273 100644 --- a/crates/uv-workspace/src/workspace.rs +++ b/crates/uv-workspace/src/workspace.rs @@ -1,6 +1,6 @@ //! Resolve the current [`ProjectWorkspace`] or [`Workspace`]. -use distribution_types::IndexSource; +use distribution_types::Index; use either::Either; use glob::{glob, GlobError, PatternError}; use pep508_rs::{MarkerTree, RequirementOrigin, VerbatimUrl}; @@ -82,7 +82,7 @@ pub struct Workspace { /// The index table from the workspace `pyproject.toml`. /// /// This table is overridden by the project indexes. - indexes: Vec, + indexes: Vec, /// The `pyproject.toml` of the workspace root. pyproject_toml: PyProjectToml, } @@ -536,7 +536,7 @@ impl Workspace { } /// The index table from the workspace `pyproject.toml`. - pub fn indexes(&self) -> &[IndexSource] { + pub fn indexes(&self) -> &[Index] { &self.indexes } diff --git a/crates/uv/src/commands/pip/compile.rs b/crates/uv/src/commands/pip/compile.rs index ea158b01aae1c..fb8ab19862291 100644 --- a/crates/uv/src/commands/pip/compile.rs +++ b/crates/uv/src/commands/pip/compile.rs @@ -8,8 +8,8 @@ use owo_colors::OwoColorize; use tracing::debug; use distribution_types::{ - DependencyMetadata, IndexCapabilities, IndexLocations, IndexSource, - NameRequirementSpecification, UnresolvedRequirementSpecification, Verbatim, + DependencyMetadata, Index, IndexCapabilities, IndexLocations, NameRequirementSpecification, + UnresolvedRequirementSpecification, Verbatim, }; use install_wheel_rs::linker::LinkMode; use pypi_types::{Requirement, SupportedEnvironments}; @@ -277,8 +277,8 @@ pub(crate) async fn pip_compile( let index_locations = index_locations.combine( extra_index_urls .into_iter() - .map(IndexSource::from_extra_index_url) - .chain(index_url.map(IndexSource::from_index_url)) + .map(Index::from_extra_index_url) + .chain(index_url.map(Index::from_index_url)) .collect(), find_links, no_index, diff --git a/crates/uv/src/commands/pip/install.rs b/crates/uv/src/commands/pip/install.rs index 0ec8d063ff921..e8290f46c245e 100644 --- a/crates/uv/src/commands/pip/install.rs +++ b/crates/uv/src/commands/pip/install.rs @@ -6,7 +6,7 @@ use owo_colors::OwoColorize; use tracing::{debug, enabled, Level}; use distribution_types::{ - DependencyMetadata, IndexLocations, IndexSource, NameRequirementSpecification, Resolution, + DependencyMetadata, Index, IndexLocations, NameRequirementSpecification, Resolution, UnresolvedRequirementSpecification, }; use install_wheel_rs::linker::LinkMode; @@ -275,8 +275,8 @@ pub(crate) async fn pip_install( let index_locations = index_locations.combine( extra_index_urls .into_iter() - .map(IndexSource::from_extra_index_url) - .chain(index_url.map(IndexSource::from_index_url)) + .map(Index::from_extra_index_url) + .chain(index_url.map(Index::from_index_url)) .collect(), find_links, no_index, diff --git a/crates/uv/src/commands/pip/sync.rs b/crates/uv/src/commands/pip/sync.rs index 66e0ca0a118df..0a0d075fdbbfb 100644 --- a/crates/uv/src/commands/pip/sync.rs +++ b/crates/uv/src/commands/pip/sync.rs @@ -5,7 +5,7 @@ use anyhow::Result; use owo_colors::OwoColorize; use tracing::debug; -use distribution_types::{DependencyMetadata, IndexLocations, IndexSource, Resolution}; +use distribution_types::{DependencyMetadata, Index, IndexLocations, Resolution}; use install_wheel_rs::linker::LinkMode; use pep508_rs::PackageName; use uv_auth::store_credentials_from_url; @@ -218,8 +218,8 @@ pub(crate) async fn pip_sync( let index_locations = index_locations.combine( extra_index_urls .into_iter() - .map(IndexSource::from_extra_index_url) - .chain(index_url.map(IndexSource::from_index_url)) + .map(Index::from_extra_index_url) + .chain(index_url.map(Index::from_index_url)) .collect(), find_links, no_index, diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index 4d778df69663a..4fd8ac9f03c8a 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -4,7 +4,7 @@ use std::path::PathBuf; use std::process; use std::str::FromStr; -use distribution_types::{DependencyMetadata, IndexLocations, IndexSource}; +use distribution_types::{DependencyMetadata, Index, IndexLocations}; use install_wheel_rs::linker::LinkMode; use pep508_rs::{ExtraName, RequirementOrigin}; use pypi_types::{Requirement, SupportedEnvironments}; @@ -1908,9 +1908,9 @@ impl From for ResolverSettings { .extra_index_url .into_iter() .flatten() - .map(IndexSource::from_extra_index_url), + .map(Index::from_extra_index_url), ) - .chain(value.index_url.into_iter().map(IndexSource::from_index_url)) + .chain(value.index_url.into_iter().map(Index::from_index_url)) .collect(), value.find_links.unwrap_or_default(), value.no_index.unwrap_or_default(), @@ -2046,9 +2046,9 @@ impl From for ResolverInstallerSettings { .extra_index_url .into_iter() .flatten() - .map(IndexSource::from_extra_index_url), + .map(Index::from_extra_index_url), ) - .chain(value.index_url.into_iter().map(IndexSource::from_index_url)) + .chain(value.index_url.into_iter().map(Index::from_index_url)) .collect(), value.find_links.unwrap_or_default(), value.no_index.unwrap_or_default(), @@ -2272,17 +2272,17 @@ impl PipSettings { args.extra_index_url .into_iter() .flatten() - .map(IndexSource::from_extra_index_url), + .map(Index::from_extra_index_url), ) - .chain(args.index_url.into_iter().map(IndexSource::from_index_url)) + .chain(args.index_url.into_iter().map(Index::from_index_url)) .chain(index.into_iter().flatten()) .chain( extra_index_url .into_iter() .flatten() - .map(IndexSource::from_extra_index_url), + .map(Index::from_extra_index_url), ) - .chain(index_url.into_iter().map(IndexSource::from_index_url)) + .chain(index_url.into_iter().map(Index::from_index_url)) .collect(), args.find_links.combine(find_links).unwrap_or_default(), args.no_index.combine(no_index).unwrap_or_default(), diff --git a/crates/uv/tests/show_settings.rs b/crates/uv/tests/show_settings.rs index 519e981767380..0bded9244d379 100644 --- a/crates/uv/tests/show_settings.rs +++ b/crates/uv/tests/show_settings.rs @@ -93,7 +93,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Pypi( VerbatimUrl { @@ -239,7 +239,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Pypi( VerbatimUrl { @@ -386,7 +386,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Pypi( VerbatimUrl { @@ -565,7 +565,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Pypi( VerbatimUrl { @@ -842,7 +842,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Pypi( VerbatimUrl { @@ -1013,7 +1013,7 @@ fn resolve_index_url() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Pypi( VerbatimUrl { @@ -1040,7 +1040,7 @@ fn resolve_index_url() -> anyhow::Result<()> { explicit: false, default: false, }, - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -1188,7 +1188,7 @@ fn resolve_index_url() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -1215,7 +1215,7 @@ fn resolve_index_url() -> anyhow::Result<()> { explicit: false, default: false, }, - IndexSource { + Index { name: None, url: Pypi( VerbatimUrl { @@ -1242,7 +1242,7 @@ fn resolve_index_url() -> anyhow::Result<()> { explicit: false, default: false, }, - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -1713,7 +1713,7 @@ fn resolve_top_level() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -1740,7 +1740,7 @@ fn resolve_top_level() -> anyhow::Result<()> { explicit: false, default: false, }, - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -1886,7 +1886,7 @@ fn resolve_top_level() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -1913,7 +1913,7 @@ fn resolve_top_level() -> anyhow::Result<()> { explicit: false, default: false, }, - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -2916,7 +2916,7 @@ fn resolve_both() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Pypi( VerbatimUrl { @@ -3089,7 +3089,7 @@ fn resolve_config_file() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Pypi( VerbatimUrl { @@ -3751,7 +3751,7 @@ fn index_priority() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -3778,7 +3778,7 @@ fn index_priority() -> anyhow::Result<()> { explicit: false, default: true, }, - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -3924,7 +3924,7 @@ fn index_priority() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -3951,7 +3951,7 @@ fn index_priority() -> anyhow::Result<()> { explicit: false, default: true, }, - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -4103,7 +4103,7 @@ fn index_priority() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -4130,7 +4130,7 @@ fn index_priority() -> anyhow::Result<()> { explicit: false, default: true, }, - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -4277,7 +4277,7 @@ fn index_priority() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -4304,7 +4304,7 @@ fn index_priority() -> anyhow::Result<()> { explicit: false, default: false, }, - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -4458,7 +4458,7 @@ fn index_priority() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -4485,7 +4485,7 @@ fn index_priority() -> anyhow::Result<()> { explicit: false, default: true, }, - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -4632,7 +4632,7 @@ fn index_priority() -> anyhow::Result<()> { settings: PipSettings { index_locations: IndexLocations { indexes: [ - IndexSource { + Index { name: None, url: Url( VerbatimUrl { @@ -4659,7 +4659,7 @@ fn index_priority() -> anyhow::Result<()> { explicit: false, default: false, }, - IndexSource { + Index { name: None, url: Url( VerbatimUrl { diff --git a/docs/concepts/dependencies.md b/docs/concepts/dependencies.md index e45ea9dcdbeb1..9afd69b961fdc 100644 --- a/docs/concepts/dependencies.md +++ b/docs/concepts/dependencies.md @@ -70,6 +70,7 @@ stands-compliant `project.dependencies` table. During development, a project may rely on a package that isn't available on PyPI. The following additional sources are supported by uv: +- Index: A package from an explicit package index. - Git: A Git repository. - URL: A remote wheel or source distribution. - Path: A local wheel, source distribution, or project directory. @@ -91,6 +92,29 @@ $ uv lock --no-sources The use of `--no-sources` will also prevent uv from discovering any [workspace members](#workspace-member) that could satisfy a given dependency. +### Index + +To pin a Python package to a specific index, add a named index to the `pyproject.toml`: + +```toml title="pyproject.toml" +[project] +dependencies = [ + "torch", +] + +[tool.uv.sources] +torch = { index = "pytorch" } + +[[tool.uv.index]] +name = "pytorch" +url = "https://download.pytorch.org/whl/cpu" +explicit = true +``` + +The `explicit` flag is optional and indicates that the index should _only_ be used for packages that +explicitly specify it in `tool.uv.sources`. If `explicit` is not set, other packages may be resolved +from the index, if not found elsewhere. + ### Git To add a Git dependency source, prefix a Git-compatible URL to clone with `git+`. diff --git a/docs/configuration/environment.md b/docs/configuration/environment.md index f744bfa1b8a4d..18bc1bb70875c 100644 --- a/docs/configuration/environment.md +++ b/docs/configuration/environment.md @@ -2,10 +2,15 @@ uv accepts the following command-line arguments as environment variables: +- `UV_INDEX`: Equivalent to the `--index` command-line argument. If set, uv will use this URL as the + base index for searching for packages. +- `UV_DEFAULT_INDEX`: Equivalent to the `--default-index` command-line argument. If set, uv will use + this space-separated list of URLs as additional indexes when searching for packages. - `UV_INDEX_URL`: Equivalent to the `--index-url` command-line argument. If set, uv will use this - URL as the base index for searching for packages. + URL as the base index for searching for packages. (Deprecated: use `UV_INDEX` instead.) - `UV_EXTRA_INDEX_URL`: Equivalent to the `--extra-index-url` command-line argument. If set, uv will use this space-separated list of URLs as additional indexes when searching for packages. + (Deprecated: use `UV_DEFAULT_INDEX` instead.) - `UV_CACHE_DIR`: Equivalent to the `--cache-dir` command-line argument. If set, uv will use this directory for caching instead of the default cache directory. - `UV_NO_CACHE`: Equivalent to the `--no-cache` command-line argument. If set, uv will not use the diff --git a/docs/configuration/index.md b/docs/configuration/index.md index 8f0bc1f3edced..38c68875fc1ec 100644 --- a/docs/configuration/index.md +++ b/docs/configuration/index.md @@ -5,6 +5,7 @@ Read about the various ways to configure uv: - [Using configuration files](./files.md) - [Using environment variables](./environment.md) - [Configuring authentication](./authentication.md) +- [Configuring package indexes](./indexes.md) Or, jump to the [settings reference](../reference/settings.md) which enumerates the available configuration options. diff --git a/docs/configuration/indexes.md b/docs/configuration/indexes.md new file mode 100644 index 0000000000000..70ef968f5f9af --- /dev/null +++ b/docs/configuration/indexes.md @@ -0,0 +1,114 @@ +# Package indexes + +By default, uv uses the [Python Package Index (PyPI)](https://pypi.org) for dependency resolution +and package installation. However, uv can be configured to use other package indexes, including +private indexes, via the `[[tool.uv.index]]` configuration option (and `--index`, its analogous +command-line option). + +## Defining an index + +To include an additional index when resolving dependencies, add a `[[tool.uv.index]]` entry to your +`pyproject.toml`: + +```toml +[[tool.uv.index]] +# Optional, explicit name for the index. +name = "pytorch" +# Required URL for the index. Expects a repository compliant with PEP 503 (the simple repository API). +url = "https://download.pytorch.org/whl/cpu" +``` + +Indexes are prioritized in the order in which they’re defined, such that the first index listed in +the configuration file is the first index consulted when resolving dependencies, with indexes +provided via the command line taking precedence over those in the configuration file. + +By default, uv includes the Python Package Index (PyPI) as the "default" index, i.e., the index used +when a package is not found on any other index. To exclude PyPI from the list of indexes, set +`default = true` on another index entry (or use the `--default-index` command-line option): + +```toml +[[tool.uv.index]] +name = "pytorch" +url = "https://download.pytorch.org/whl/cpu" +default = true +``` + +The default index is always treated as lowest priority, regardless of its position in the list of +indexes. + +## Pinning a package to an index + +A package can be pinned to a specific index by specifying the index in its `tool.uv.sources` entry. +For example, to ensure that `torch` is _always_ installed from the `pytorch` index, add the +following to your `pyproject.toml`: + +```toml +[tool.uv.sources] +torch = { index = "pytorch" } + +[[tool.uv.index]] +name = "pytorch" +url = "https://download.pytorch.org/whl/cpu" +``` + +An index can be marked as `explicit = true` to prevent packages from being installed from that index +unless explicitly pinned to it. For example, to ensure that `torch` is _only_ installed from the +`pytorch` index, add the following to your `pyproject.toml`: + +```toml +[tool.uv.sources] +torch = { index = "pytorch" } + +[[tool.uv.index]] +name = "pytorch" +url = "https://download.pytorch.org/whl/cpu" +explicit = true +``` + +Named indexes referenced via `tool.uv.sources` must be defined within the project's `pyproject.toml` +file; indexes provided via the command-line, environment variables, or user-level configuration will +not be recognized. + +## Searching across multiple indexes + +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 (`first-match`). + +For example, if an internal index is specified via `[[tool.uv.index]]`, uv's behavior is such that +if a package exists on that internal index, it will _always_ be installed from that internal index, +and never from PyPI. The intent is to prevent "dependency confusion" attacks, in which an attacker +publishes a malicious package on PyPI with the same name as an internal package, thus causing the +malicious package to be installed instead of the internal package. See, for example, +[the `torchtriton` attack](https://pytorch.org/blog/compromised-nightly-dependency/) from +December 2022. + +Users can opt in to alternate index behaviors via the`--index-strategy` command-line option, or the +`UV_INDEX_STRATEGY` environment variable, which supports the following values: + +- `first-match` (default): Search for each package across all indexes, limiting the candidate + versions to those present in the first index that contains the package. +- `unsafe-first-match`: Search for each package across all indexes, but prefer the first index with + a compatible version, even if newer versions are available on other indexes. +- `unsafe-best-match`: Search for each package across all indexes, and select the best version from + the combined set of candidate versions. + +While `unsafe-best-match` is the closest to pip's behavior, it exposes users to the risk of +"dependency confusion" attacks. + +## `--index-url` and `--extra-index-url` + +In addition to the `[[tool.uv.index]]` configuration option, uv supports pip-style `--index-url` and +`--extra-index-url` command-line options for compatibility, where `--index-url` defines the default +index and `--extra-index-url` defines additional indexes. + +These options can be used in conjunction with the `[[tool.uv.index]]` configuration option, and use +the same prioritization rules: + +- The default index is always treated as lowest priority, whether defined via the legacy + `--index-url` argument, the recommended `--default-index` argument, or a `[[tool.uv.index]]` entry + with `default = true`. +- Indexes are consulted in the order in which they’re defined, either via the legacy + `--extra-index-url` argument, the recommended `--index` argument, or `[[tool.uv.index]]` entries. + +In effect, `--index-url` and `--extra-index-url` can be thought of as unnamed `[[tool.uv.index]]` +entries, with `default = true` enabled for the former. diff --git a/docs/pip/compatibility.md b/docs/pip/compatibility.md index 128ff23d8956f..cab59ca1769be 100644 --- a/docs/pip/compatibility.md +++ b/docs/pip/compatibility.md @@ -148,10 +148,9 @@ supports the following values: While `unsafe-best-match` is the closest to `pip`'s behavior, it exposes users to the risk of "dependency confusion" attacks. -In the future, uv will support pinning packages to dedicated indexes (see: -[#171](https://github.com/astral-sh/uv/issues/171)). Additionally, -[PEP 708](https://peps.python.org/pep-0708/) is a provisional standard that aims to address the -"dependency confusion" issue across package registries and installers. +uv also supports pinning packages to dedicated indexes (see: +[_Indexes_](../configuration/indexes.md#pinning-a-package-to-an-index)), such that a given package +is _always_ installed from a specific index. ## PEP 517 build isolation diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 46e3d6b5e5dc7..fdd1f38ca2e53 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -163,7 +163,7 @@ uv run [OPTIONS]
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -172,7 +172,7 @@ uv run [OPTIONS]

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -716,7 +716,7 @@ uv add [OPTIONS] >
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -725,7 +725,7 @@ uv add [OPTIONS] >

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -1050,7 +1050,7 @@ uv remove [OPTIONS] ...
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -1059,7 +1059,7 @@ uv remove [OPTIONS] ...

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -1372,7 +1372,7 @@ uv sync [OPTIONS]
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -1381,7 +1381,7 @@ uv sync [OPTIONS]

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -1691,7 +1691,7 @@ uv lock [OPTIONS]
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -1700,7 +1700,7 @@ uv lock [OPTIONS]

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -2000,7 +2000,7 @@ uv export [OPTIONS]
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -2009,7 +2009,7 @@ uv export [OPTIONS]

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -2316,7 +2316,7 @@ uv tree [OPTIONS]
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -2325,7 +2325,7 @@ uv tree [OPTIONS]

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -2705,7 +2705,7 @@ uv tool run [OPTIONS] [COMMAND]
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -2714,7 +2714,7 @@ uv tool run [OPTIONS] [COMMAND]

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -3011,7 +3011,7 @@ uv tool install [OPTIONS]
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -3020,7 +3020,7 @@ uv tool install [OPTIONS]

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -3309,7 +3309,7 @@ uv tool upgrade [OPTIONS] ...
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -3318,7 +3318,7 @@ uv tool upgrade [OPTIONS] ...

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -4893,7 +4893,7 @@ uv pip compile [OPTIONS] ...
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -4902,7 +4902,7 @@ uv pip compile [OPTIONS] ...

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -5297,7 +5297,7 @@ uv pip sync [OPTIONS] ...
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -5306,7 +5306,7 @@ uv pip sync [OPTIONS] ...

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -5657,7 +5657,7 @@ uv pip install [OPTIONS] |--editable
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -5666,7 +5666,7 @@ uv pip install [OPTIONS] |--editable May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -6844,7 +6844,7 @@ uv venv [OPTIONS] [PATH]
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -6853,7 +6853,7 @@ uv venv [OPTIONS] [PATH]

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

@@ -7109,7 +7109,7 @@ uv build [OPTIONS] [SRC]
--help, -h

Display the concise help for this command

-
--index index

The URLs of additional package indexes to use.

+
--index index

The URLs to use when resolving dependencies, in addition to the default index.

Accepts either a repository compliant with PEP 503 (the simple repository API), or a local directory laid out in the same format.

@@ -7118,7 +7118,7 @@ uv build [OPTIONS] [SRC]

May also be set with the UV_INDEX environment variable.

--index-strategy index-strategy

The strategy to use when resolving against multiple index URLs.

-

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 (first-match). This prevents "dependency confusion" attacks, whereby an attack can upload a malicious package under the same name to a secondary.

+

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 (first-match). This prevents "dependency confusion" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.

May also be set with the UV_INDEX_STRATEGY environment variable.

Possible values:

diff --git a/docs/reference/settings.md b/docs/reference/settings.md index 3419f51e60bab..03e7dd2c3c8aa 100644 --- a/docs/reference/settings.md +++ b/docs/reference/settings.md @@ -640,7 +640,7 @@ formats described above. ### [`index`](#index) {: #index } -The indexes to use when resolving dependencies. +The package indexes to use when resolving dependencies. Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/) (the simple repository API), or a local directory laid out in the same format. @@ -696,8 +696,8 @@ The strategy to use when resolving against multiple index URLs. 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 (`first-match`). This prevents -"dependency confusion" attacks, whereby an attack can upload a malicious package under the -same name to a secondary. +"dependency confusion" attacks, whereby an attacker can upload a malicious package under the +same name to an alternate index. **Default value**: `"first-index"` @@ -2012,8 +2012,8 @@ The strategy to use when resolving against multiple index URLs. 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 (`first-match`). This prevents -"dependency confusion" attacks, whereby an attack can upload a malicious package under the -same name to a secondary. +"dependency confusion" attacks, whereby an attacker can upload a malicious package under the +same name to an alternate index. **Default value**: `"first-index"` diff --git a/mkdocs.template.yml b/mkdocs.template.yml index db95f32ae44cb..3c61340eea277 100644 --- a/mkdocs.template.yml +++ b/mkdocs.template.yml @@ -106,6 +106,7 @@ nav: - Configuration files: configuration/files.md - Environment variables: configuration/environment.md - Authentication: configuration/authentication.md + - Package indexes: configuration/indexes.md - Integration guides: - guides/integration/index.md - Docker: guides/integration/docker.md diff --git a/uv.schema.json b/uv.schema.json index dbdca349f95d2..7a1fe99242bd1 100644 --- a/uv.schema.json +++ b/uv.schema.json @@ -154,11 +154,11 @@ "null" ], "items": { - "$ref": "#/definitions/IndexSource" + "$ref": "#/definitions/Index" } }, "index-strategy": { - "description": "The strategy to use when resolving against multiple index URLs.\n\nBy 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 (`first-match`). This prevents \"dependency confusion\" attacks, whereby an attack can upload a malicious package under the same name to a secondary.", + "description": "The strategy to use when resolving against multiple index URLs.\n\nBy 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 (`first-match`). This prevents \"dependency confusion\" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.", "anyOf": [ { "$ref": "#/definitions/IndexStrategy" @@ -555,7 +555,7 @@ "description": "The path to a directory of distributions, or a URL to an HTML file with a flat listing of distributions.", "type": "string" }, - "IndexSource": { + "Index": { "type": "object", "required": [ "url" @@ -842,7 +842,7 @@ ] }, "index-strategy": { - "description": "The strategy to use when resolving against multiple index URLs.\n\nBy 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 (`first-match`). This prevents \"dependency confusion\" attacks, whereby an attack can upload a malicious package under the same name to a secondary.", + "description": "The strategy to use when resolving against multiple index URLs.\n\nBy 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 (`first-match`). This prevents \"dependency confusion\" attacks, whereby an attacker can upload a malicious package under the same name to an alternate index.", "anyOf": [ { "$ref": "#/definitions/IndexStrategy"