mirror of https://github.com/astral-sh/uv
Pass around index with associated metadata (#12406)
## Summary This PR modifies the requirement source entities to store a (new) container struct that wraps `IndexUrl`. This will allow us to store user-defined metadata alongside `IndexUrl`, and propagate that metadata throughout resolution. Specifically, I need to store the "kind" of the index (Simple API vs. `--find-links`), but I also ran into this problem when I tried to add support for overriding `Cache-Control` headers on a per-index basis: at present, we have no way to passing around metadata alongside an `IndexUrl`.
This commit is contained in:
parent
c3442e822e
commit
1865e0a6ee
|
|
@ -3,7 +3,17 @@ use url::Url;
|
|||
|
||||
/// When to use authentication.
|
||||
#[derive(
|
||||
Copy, Clone, Debug, Default, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize,
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
Default,
|
||||
Hash,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Ord,
|
||||
PartialOrd,
|
||||
serde::Serialize,
|
||||
serde::Deserialize,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ use reqwest_middleware::ClientWithMiddleware;
|
|||
use tokio::sync::Semaphore;
|
||||
use tracing::{info_span, instrument, trace, warn, Instrument};
|
||||
use url::Url;
|
||||
use uv_auth::UrlAuthPolicies;
|
||||
|
||||
use uv_auth::UrlAuthPolicies;
|
||||
use uv_cache::{Cache, CacheBucket, CacheEntry, WheelCache};
|
||||
use uv_configuration::KeyringProviderType;
|
||||
use uv_configuration::{IndexStrategy, TrustedHost};
|
||||
use uv_distribution_filename::{DistFilename, SourceDistFilename, WheelFilename};
|
||||
use uv_distribution_types::{
|
||||
BuiltDist, File, FileLocation, Index, IndexCapabilities, IndexUrl, IndexUrls, Name,
|
||||
BuiltDist, File, FileLocation, IndexCapabilities, IndexMetadataRef, IndexUrl, IndexUrls, Name,
|
||||
};
|
||||
use uv_metadata::{read_metadata_async_seek, read_metadata_async_stream};
|
||||
use uv_normalize::PackageName;
|
||||
|
|
@ -255,16 +255,17 @@ impl RegistryClient {
|
|||
}
|
||||
|
||||
/// Return the appropriate index URLs for the given [`PackageName`].
|
||||
fn index_urls_for(&self, package_name: &PackageName) -> impl Iterator<Item = &IndexUrl> {
|
||||
fn index_urls_for(&self, package_name: &PackageName) -> impl Iterator<Item = IndexMetadataRef> {
|
||||
self.torch_backend
|
||||
.as_ref()
|
||||
.and_then(|torch_backend| {
|
||||
torch_backend
|
||||
.applies_to(package_name)
|
||||
.then(|| torch_backend.index_urls())
|
||||
.map(|indexes| indexes.map(IndexMetadataRef::from))
|
||||
})
|
||||
.map(Either::Left)
|
||||
.unwrap_or_else(|| Either::Right(self.index_urls.indexes().map(Index::url)))
|
||||
.unwrap_or_else(|| Either::Right(self.index_urls.indexes().map(IndexMetadataRef::from)))
|
||||
}
|
||||
|
||||
/// Return the appropriate [`IndexStrategy`] for the given [`PackageName`].
|
||||
|
|
@ -288,10 +289,10 @@ impl RegistryClient {
|
|||
pub async fn simple<'index>(
|
||||
&'index self,
|
||||
package_name: &PackageName,
|
||||
index: Option<&'index IndexUrl>,
|
||||
index: Option<IndexMetadataRef<'index>>,
|
||||
capabilities: &IndexCapabilities,
|
||||
download_concurrency: &Semaphore,
|
||||
) -> Result<Vec<(&'index IndexUrl, OwnedArchive<SimpleMetadata>)>, Error> {
|
||||
) -> Result<Vec<(IndexMetadataRef<'index>, OwnedArchive<SimpleMetadata>)>, Error> {
|
||||
// If `--no-index` is specified, avoid fetching regardless of whether the index is implicit,
|
||||
// explicit, etc.
|
||||
if self.index_urls.no_index() {
|
||||
|
|
@ -312,7 +313,7 @@ impl RegistryClient {
|
|||
for index in indexes {
|
||||
let _permit = download_concurrency.acquire().await;
|
||||
if let Some(metadata) = self
|
||||
.simple_single_index(package_name, index, capabilities)
|
||||
.simple_single_index(package_name, index.url(), capabilities)
|
||||
.await?
|
||||
{
|
||||
results.push((index, metadata));
|
||||
|
|
@ -327,7 +328,7 @@ impl RegistryClient {
|
|||
.map(|index| async move {
|
||||
let _permit = download_concurrency.acquire().await;
|
||||
let metadata = self
|
||||
.simple_single_index(package_name, index, capabilities)
|
||||
.simple_single_index(package_name, index.url(), capabilities)
|
||||
.await?;
|
||||
Ok((index, metadata))
|
||||
})
|
||||
|
|
@ -369,9 +370,9 @@ impl RegistryClient {
|
|||
capabilities: &IndexCapabilities,
|
||||
) -> Result<Option<OwnedArchive<SimpleMetadata>>, Error> {
|
||||
// Format the URL for PyPI.
|
||||
let mut url: Url = index.clone().into();
|
||||
let mut url = index.url().clone();
|
||||
url.path_segments_mut()
|
||||
.map_err(|()| ErrorKind::CannotBeABase(index.clone().into()))?
|
||||
.map_err(|()| ErrorKind::CannotBeABase(index.url().clone()))?
|
||||
.pop_if_empty()
|
||||
.push(package_name.as_ref())
|
||||
// The URL *must* end in a trailing slash for proper relative path behavior
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@ use crate::index_name::{IndexName, IndexNameError};
|
|||
use crate::origin::Origin;
|
||||
use crate::{IndexUrl, IndexUrlError};
|
||||
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(
|
||||
Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, serde::Serialize, serde::Deserialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Index {
|
||||
|
|
@ -200,6 +202,20 @@ impl Index {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<IndexUrl> for Index {
|
||||
fn from(value: IndexUrl) -> Self {
|
||||
Self {
|
||||
name: None,
|
||||
url: value,
|
||||
explicit: false,
|
||||
default: false,
|
||||
origin: None,
|
||||
publish_url: None,
|
||||
authenticate: AuthPolicy::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Index {
|
||||
type Err = IndexSourceError;
|
||||
|
||||
|
|
@ -235,6 +251,76 @@ impl FromStr for Index {
|
|||
}
|
||||
}
|
||||
|
||||
/// An [`IndexUrl`] along with the metadata necessary to query the index.
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct IndexMetadata {
|
||||
pub url: IndexUrl,
|
||||
// /// The type of the index.
|
||||
// ///
|
||||
// /// Indexes can either be PEP 503-compliant (i.e., a registry implementing the Simple API) or
|
||||
// /// structured as a flat list of distributions (e.g., `--find-links`). In both cases, indexes
|
||||
// /// can point to either local or remote resources.
|
||||
// #[serde(default)]
|
||||
// pub r#type: IndexKind,
|
||||
}
|
||||
|
||||
impl IndexMetadata {
|
||||
/// Return a reference to the [`IndexMetadata`].
|
||||
pub fn as_ref(&self) -> IndexMetadataRef<'_> {
|
||||
let Self { url } = self;
|
||||
IndexMetadataRef { url }
|
||||
}
|
||||
|
||||
/// Consume the [`IndexMetadata`] and return the [`IndexUrl`].
|
||||
pub fn into_url(self) -> IndexUrl {
|
||||
self.url
|
||||
}
|
||||
}
|
||||
|
||||
/// A reference to an [`IndexMetadata`].
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct IndexMetadataRef<'a> {
|
||||
pub url: &'a IndexUrl,
|
||||
}
|
||||
|
||||
impl IndexMetadata {
|
||||
/// Return the [`IndexUrl`] of the index.
|
||||
pub fn url(&self) -> &IndexUrl {
|
||||
&self.url
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMetadataRef<'_> {
|
||||
/// Return the [`IndexUrl`] of the index.
|
||||
pub fn url(&self) -> &IndexUrl {
|
||||
self.url
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a IndexMetadata> for IndexMetadataRef<'a> {
|
||||
fn from(value: &'a IndexMetadata) -> Self {
|
||||
Self { url: &value.url }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a IndexUrl> for IndexMetadataRef<'a> {
|
||||
fn from(value: &'a IndexUrl) -> Self {
|
||||
Self { url: value }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Index> for IndexMetadataRef<'a> {
|
||||
fn from(value: &'a Index) -> Self {
|
||||
Self { url: &value.url }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<IndexUrl> for IndexMetadata {
|
||||
fn from(value: IndexUrl) -> Self {
|
||||
Self { url: value }
|
||||
}
|
||||
}
|
||||
|
||||
/// An error that can occur when parsing an [`Index`].
|
||||
#[derive(Error, Debug)]
|
||||
pub enum IndexSourceError {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use uv_small_str::SmallString;
|
|||
/// The normalized name of an index.
|
||||
///
|
||||
/// Index names may contain letters, digits, hyphens, underscores, and periods, and must be ASCII.
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, serde::Serialize)]
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, serde::Serialize)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct IndexName(SmallString);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/// The origin of a piece of configuration.
|
||||
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub enum Origin {
|
||||
/// The setting was provided via the CLI.
|
||||
Cli,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ use uv_pep440::VersionSpecifiers;
|
|||
use uv_pep508::{
|
||||
marker, MarkerEnvironment, MarkerTree, RequirementOrigin, VerbatimUrl, VersionOrUrl,
|
||||
};
|
||||
|
||||
use crate::{IndexMetadata, IndexUrl};
|
||||
|
||||
use uv_pypi_types::{
|
||||
ConflictItem, Hashes, ParsedArchiveUrl, ParsedDirectoryUrl, ParsedGitUrl, ParsedPathUrl,
|
||||
ParsedUrl, ParsedUrlError, VerbatimParsedUrl,
|
||||
|
|
@ -320,7 +323,7 @@ impl Display for Requirement {
|
|||
} => {
|
||||
write!(f, "{specifier}")?;
|
||||
if let Some(index) = index {
|
||||
write!(f, " (index: {index})")?;
|
||||
write!(f, " (index: {})", index.url)?;
|
||||
}
|
||||
}
|
||||
RequirementSource::Url { url, .. } => {
|
||||
|
|
@ -368,7 +371,7 @@ pub enum RequirementSource {
|
|||
Registry {
|
||||
specifier: VersionSpecifiers,
|
||||
/// Choose a version from the index at the given URL.
|
||||
index: Option<Url>,
|
||||
index: Option<IndexMetadata>,
|
||||
/// The conflict item associated with the source, if any.
|
||||
conflict: Option<ConflictItem>,
|
||||
},
|
||||
|
|
@ -600,7 +603,7 @@ impl Display for RequirementSource {
|
|||
} => {
|
||||
write!(f, "{specifier}")?;
|
||||
if let Some(index) = index {
|
||||
write!(f, " (index: {index})")?;
|
||||
write!(f, " (index: {})", index.url)?;
|
||||
}
|
||||
}
|
||||
Self::Url { url, .. } => {
|
||||
|
|
@ -662,12 +665,13 @@ impl From<RequirementSource> for RequirementSourceWire {
|
|||
match value {
|
||||
RequirementSource::Registry {
|
||||
specifier,
|
||||
mut index,
|
||||
index,
|
||||
conflict,
|
||||
} => {
|
||||
if let Some(index) = index.as_mut() {
|
||||
redact_credentials(index);
|
||||
}
|
||||
let index = index.map(|index| index.url.into_url()).map(|mut index| {
|
||||
redact_credentials(&mut index);
|
||||
index
|
||||
});
|
||||
Self::Registry {
|
||||
specifier,
|
||||
index,
|
||||
|
|
@ -775,7 +779,8 @@ impl TryFrom<RequirementSourceWire> for RequirementSource {
|
|||
conflict,
|
||||
} => Ok(Self::Registry {
|
||||
specifier,
|
||||
index,
|
||||
index: index
|
||||
.map(|index| IndexMetadata::from(IndexUrl::from(VerbatimUrl::from_url(index)))),
|
||||
conflict,
|
||||
}),
|
||||
RequirementSourceWire::Git { git } => {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ use uv_normalize::{ExtraName, GroupName, PackageName};
|
|||
use uv_pep508::MarkerTree;
|
||||
use uv_pypi_types::{HashDigest, HashDigests};
|
||||
|
||||
use crate::{BuiltDist, Diagnostic, Dist, Name, RequirementSource, ResolvedDist, SourceDist};
|
||||
use crate::{
|
||||
BuiltDist, Diagnostic, Dist, IndexMetadata, Name, RequirementSource, ResolvedDist, SourceDist,
|
||||
};
|
||||
|
||||
/// A set of packages pinned at specific versions.
|
||||
///
|
||||
|
|
@ -229,7 +231,7 @@ impl From<&ResolvedDist> for RequirementSource {
|
|||
wheel.filename.version.clone(),
|
||||
),
|
||||
),
|
||||
index: Some(wheel.index.url().clone()),
|
||||
index: Some(IndexMetadata::from(wheel.index.clone())),
|
||||
conflict: None,
|
||||
}
|
||||
}
|
||||
|
|
@ -252,7 +254,7 @@ impl From<&ResolvedDist> for RequirementSource {
|
|||
specifier: uv_pep440::VersionSpecifiers::from(
|
||||
uv_pep440::VersionSpecifier::equals_version(sdist.version.clone()),
|
||||
),
|
||||
index: Some(sdist.index.url().clone()),
|
||||
index: Some(IndexMetadata::from(sdist.index.clone())),
|
||||
conflict: None,
|
||||
},
|
||||
Dist::Source(SourceDist::DirectUrl(sdist)) => {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use url::Url;
|
|||
|
||||
use uv_distribution_filename::DistExtension;
|
||||
use uv_distribution_types::{
|
||||
Index, IndexLocations, IndexName, Origin, Requirement, RequirementSource,
|
||||
Index, IndexLocations, IndexMetadata, IndexName, Origin, Requirement, RequirementSource,
|
||||
};
|
||||
use uv_git_types::{GitReference, GitUrl, GitUrlParseError};
|
||||
use uv_normalize::{ExtraName, GroupName, PackageName};
|
||||
|
|
@ -222,7 +222,9 @@ impl LoweredRequirement {
|
|||
.find(|Index { name, .. }| {
|
||||
name.as_ref().is_some_and(|name| *name == index)
|
||||
})
|
||||
.map(|Index { url: index, .. }| index.clone())
|
||||
.map(|index| IndexMetadata {
|
||||
url: index.url.clone(),
|
||||
})
|
||||
else {
|
||||
return Err(LoweringError::MissingIndex(
|
||||
requirement.name.clone(),
|
||||
|
|
@ -238,7 +240,7 @@ impl LoweredRequirement {
|
|||
})
|
||||
}
|
||||
});
|
||||
let source = registry_source(&requirement, index.into_url(), conflict);
|
||||
let source = registry_source(&requirement, index, conflict);
|
||||
(source, marker)
|
||||
}
|
||||
Source::Workspace {
|
||||
|
|
@ -445,7 +447,9 @@ impl LoweredRequirement {
|
|||
.find(|Index { name, .. }| {
|
||||
name.as_ref().is_some_and(|name| *name == index)
|
||||
})
|
||||
.map(|Index { url: index, .. }| index.clone())
|
||||
.map(|index| IndexMetadata {
|
||||
url: index.url.clone(),
|
||||
})
|
||||
else {
|
||||
return Err(LoweringError::MissingIndex(
|
||||
requirement.name.clone(),
|
||||
|
|
@ -453,7 +457,7 @@ impl LoweredRequirement {
|
|||
));
|
||||
};
|
||||
let conflict = None;
|
||||
let source = registry_source(&requirement, index.into_url(), conflict);
|
||||
let source = registry_source(&requirement, index, conflict);
|
||||
(source, marker)
|
||||
}
|
||||
Source::Workspace { .. } => {
|
||||
|
|
@ -627,7 +631,7 @@ fn url_source(
|
|||
/// Convert a registry source into a [`RequirementSource`].
|
||||
fn registry_source(
|
||||
requirement: &uv_pep508::Requirement<VerbatimParsedUrl>,
|
||||
index: Url,
|
||||
index: IndexMetadata,
|
||||
conflict: Option<ConflictItem>,
|
||||
) -> RequirementSource {
|
||||
match &requirement.version_or_url {
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ pub async fn check_url(
|
|||
let response = match registry_client
|
||||
.simple(
|
||||
filename.name(),
|
||||
Some(index_url),
|
||||
Some(index_url.into()),
|
||||
index_capabilities,
|
||||
download_concurrency,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_hash::FxHashMap;
|
||||
use uv_distribution_types::IndexUrl;
|
||||
use uv_distribution_types::IndexMetadata;
|
||||
use uv_normalize::PackageName;
|
||||
|
||||
use crate::resolver::ResolverEnvironment;
|
||||
|
|
@ -7,24 +7,24 @@ use crate::ResolveError;
|
|||
|
||||
/// See [`crate::resolver::ForkState`].
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub(crate) struct ForkIndexes(FxHashMap<PackageName, IndexUrl>);
|
||||
pub(crate) struct ForkIndexes(FxHashMap<PackageName, IndexMetadata>);
|
||||
|
||||
impl ForkIndexes {
|
||||
/// Get the [`IndexUrl`] previously used for a package in this fork.
|
||||
pub(crate) fn get(&self, package_name: &PackageName) -> Option<&IndexUrl> {
|
||||
/// Get the [`Index`] previously used for a package in this fork.
|
||||
pub(crate) fn get(&self, package_name: &PackageName) -> Option<&IndexMetadata> {
|
||||
self.0.get(package_name)
|
||||
}
|
||||
|
||||
/// Check that this is the only [`IndexUrl`] used for this package in this fork.
|
||||
/// Check that this is the only [`Index`] used for this package in this fork.
|
||||
pub(crate) fn insert(
|
||||
&mut self,
|
||||
package_name: &PackageName,
|
||||
index: &IndexUrl,
|
||||
index: &IndexMetadata,
|
||||
env: &ResolverEnvironment,
|
||||
) -> Result<(), ResolveError> {
|
||||
if let Some(previous) = self.0.insert(package_name.clone(), index.clone()) {
|
||||
if &previous != index {
|
||||
let mut conflicts = vec![previous.to_string(), index.to_string()];
|
||||
let mut conflicts = vec![previous.url.to_string(), index.url.to_string()];
|
||||
conflicts.sort();
|
||||
return Err(ResolveError::ConflictingIndexesForEnvironment {
|
||||
package_name: package_name.clone(),
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ use uv_distribution_filename::{
|
|||
use uv_distribution_types::{
|
||||
redact_credentials, BuiltDist, DependencyMetadata, DirectUrlBuiltDist, DirectUrlSourceDist,
|
||||
DirectorySourceDist, Dist, DistributionMetadata, FileLocation, GitSourceDist, IndexLocations,
|
||||
IndexUrl, Name, PathBuiltDist, PathSourceDist, RegistryBuiltDist, RegistryBuiltWheel,
|
||||
RegistrySourceDist, RemoteSource, Requirement, RequirementSource, ResolvedDist, StaticMetadata,
|
||||
ToUrlError, UrlString,
|
||||
IndexMetadata, IndexUrl, Name, PathBuiltDist, PathSourceDist, RegistryBuiltDist,
|
||||
RegistryBuiltWheel, RegistrySourceDist, RemoteSource, Requirement, RequirementSource,
|
||||
ResolvedDist, StaticMetadata, ToUrlError, UrlString,
|
||||
};
|
||||
use uv_fs::{relative_to, PortablePath, PortablePathBuf};
|
||||
use uv_git::{RepositoryReference, ResolvedRepositoryReference};
|
||||
|
|
@ -4563,12 +4563,17 @@ fn normalize_requirement(
|
|||
}
|
||||
RequirementSource::Registry {
|
||||
specifier,
|
||||
mut index,
|
||||
index,
|
||||
conflict,
|
||||
} => {
|
||||
if let Some(index) = index.as_mut() {
|
||||
redact_credentials(index);
|
||||
}
|
||||
// Round-trip the index to remove anything apart from the URL.
|
||||
let index = index
|
||||
.map(|index| index.url.into_url())
|
||||
.map(|mut index| {
|
||||
redact_credentials(&mut index);
|
||||
index
|
||||
})
|
||||
.map(|index| IndexMetadata::from(IndexUrl::from(VerbatimUrl::from_url(index))));
|
||||
Ok(Requirement {
|
||||
name: requirement.name,
|
||||
extras: requirement.extras,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use rustc_hash::FxHashMap;
|
|||
use uv_configuration::{IndexStrategy, NoBinary, NoBuild};
|
||||
use uv_distribution_types::{
|
||||
IncompatibleDist, IncompatibleSource, IncompatibleWheel, Index, IndexCapabilities,
|
||||
IndexLocations, IndexUrl,
|
||||
IndexLocations, IndexMetadata, IndexUrl,
|
||||
};
|
||||
use uv_normalize::PackageName;
|
||||
use uv_pep440::{Version, VersionSpecifiers};
|
||||
|
|
@ -727,7 +727,7 @@ impl PubGrubReportFormatter<'_> {
|
|||
env: &ResolverEnvironment,
|
||||
tags: Option<&Tags>,
|
||||
) -> Option<PubGrubHint> {
|
||||
let response = if let Some(url) = fork_indexes.get(name) {
|
||||
let response = if let Some(url) = fork_indexes.get(name).map(IndexMetadata::url) {
|
||||
index.explicit().get(&(name.clone(), url.clone()))
|
||||
} else {
|
||||
index.implicit().get(name)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@ use crate::resolver::Request;
|
|||
use crate::{
|
||||
InMemoryIndex, PythonRequirement, ResolveError, ResolverEnvironment, VersionsResponse,
|
||||
};
|
||||
use uv_distribution_types::{CompatibleDist, DistributionMetadata, IndexCapabilities, IndexUrl};
|
||||
use uv_distribution_types::{
|
||||
CompatibleDist, DistributionMetadata, IndexCapabilities, IndexMetadata,
|
||||
};
|
||||
use uv_normalize::PackageName;
|
||||
use uv_pep440::Version;
|
||||
use uv_pep508::MarkerTree;
|
||||
|
|
@ -81,7 +83,7 @@ impl BatchPrefetcher {
|
|||
pub(crate) fn prefetch_batches(
|
||||
&mut self,
|
||||
next: &PubGrubPackage,
|
||||
index: Option<&IndexUrl>,
|
||||
index: Option<&IndexMetadata>,
|
||||
version: &Version,
|
||||
current_range: &Range<Version>,
|
||||
unchangeable_constraints: Option<&Term<Range<Version>>>,
|
||||
|
|
@ -110,7 +112,7 @@ impl BatchPrefetcher {
|
|||
self.prefetch_runner
|
||||
.index
|
||||
.explicit()
|
||||
.wait_blocking(&(name.clone(), index.clone()))
|
||||
.wait_blocking(&(name.clone(), index.url().clone()))
|
||||
.ok_or_else(|| ResolveError::UnregisteredTask(name.to_string()))?
|
||||
} else {
|
||||
self.prefetch_runner
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use uv_distribution_types::{IndexUrl, RequirementSource};
|
||||
use uv_distribution_types::{IndexMetadata, RequirementSource};
|
||||
use uv_normalize::PackageName;
|
||||
use uv_pep508::VerbatimUrl;
|
||||
use uv_pypi_types::ConflictItem;
|
||||
|
||||
use crate::resolver::ForkMap;
|
||||
|
|
@ -24,7 +23,7 @@ pub(crate) struct Indexes(ForkMap<Entry>);
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Entry {
|
||||
index: IndexUrl,
|
||||
index: IndexMetadata,
|
||||
conflict: Option<ConflictItem>,
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +45,9 @@ impl Indexes {
|
|||
else {
|
||||
continue;
|
||||
};
|
||||
let index = IndexUrl::from(VerbatimUrl::from_url(index.clone()));
|
||||
let index = IndexMetadata {
|
||||
url: index.url.clone(),
|
||||
};
|
||||
let conflict = conflict.clone();
|
||||
indexes.add(&requirement, Entry { index, conflict });
|
||||
}
|
||||
|
|
@ -60,7 +61,7 @@ impl Indexes {
|
|||
}
|
||||
|
||||
/// Return the explicit index used for a package in the given fork.
|
||||
pub(crate) fn get(&self, name: &PackageName, env: &ResolverEnvironment) -> Vec<&IndexUrl> {
|
||||
pub(crate) fn get(&self, name: &PackageName, env: &ResolverEnvironment) -> Vec<&IndexMetadata> {
|
||||
let entries = self.0.get(name, env);
|
||||
entries
|
||||
.iter()
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ use uv_distribution::DistributionDatabase;
|
|||
use uv_distribution_types::{
|
||||
BuiltDist, CompatibleDist, DerivationChain, Dist, DistErrorKind, DistributionMetadata,
|
||||
IncompatibleDist, IncompatibleSource, IncompatibleWheel, IndexCapabilities, IndexLocations,
|
||||
IndexUrl, InstalledDist, PythonRequirementKind, RemoteSource, Requirement, ResolvedDist,
|
||||
ResolvedDistRef, SourceDist, VersionOrUrlRef,
|
||||
IndexMetadata, IndexUrl, InstalledDist, PythonRequirementKind, RemoteSource, Requirement,
|
||||
ResolvedDist, ResolvedDistRef, SourceDist, VersionOrUrlRef,
|
||||
};
|
||||
use uv_git::GitResolver;
|
||||
use uv_normalize::{ExtraName, GroupName, PackageName};
|
||||
|
|
@ -494,7 +494,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
let decision = self.choose_version(
|
||||
next_package,
|
||||
next_id,
|
||||
index,
|
||||
index.map(IndexMetadata::url),
|
||||
term_intersection.unwrap_positive(),
|
||||
&mut state.pins,
|
||||
&preferences,
|
||||
|
|
@ -925,7 +925,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
&self,
|
||||
package: &PubGrubPackage,
|
||||
url: Option<&VerbatimParsedUrl>,
|
||||
index: Option<&IndexUrl>,
|
||||
index: Option<&IndexMetadata>,
|
||||
request_sink: &Sender<Request>,
|
||||
) -> Result<(), ResolveError> {
|
||||
// Ignore unresolved URL packages, i.e., packages that use a direct URL in some forks.
|
||||
|
|
@ -945,7 +945,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
&self,
|
||||
package: &PubGrubPackage,
|
||||
url: Option<&VerbatimParsedUrl>,
|
||||
index: Option<&IndexUrl>,
|
||||
index: Option<&IndexMetadata>,
|
||||
request_sink: &Sender<Request>,
|
||||
) -> Result<(), ResolveError> {
|
||||
// Only request real packages.
|
||||
|
|
@ -969,7 +969,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
if self
|
||||
.index
|
||||
.explicit()
|
||||
.register((name.clone(), index.clone()))
|
||||
.register((name.clone(), index.url().clone()))
|
||||
{
|
||||
request_sink.blocking_send(Request::Package(name.clone(), Some(index.clone())))?;
|
||||
}
|
||||
|
|
@ -2249,7 +2249,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
|
||||
Ok(Some(Response::Package(
|
||||
package_name,
|
||||
index,
|
||||
index.map(IndexMetadata::into_url),
|
||||
package_versions,
|
||||
)))
|
||||
}
|
||||
|
|
@ -2449,7 +2449,9 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
|
|||
continue;
|
||||
}
|
||||
let versions_response = if let Some(index) = fork_indexes.get(name) {
|
||||
self.index.explicit().get(&(name.clone(), index.clone()))
|
||||
self.index
|
||||
.explicit()
|
||||
.get(&(name.clone(), index.url().clone()))
|
||||
} else {
|
||||
self.index.implicit().get(name)
|
||||
};
|
||||
|
|
@ -3166,7 +3168,7 @@ impl ResolutionDependencyEdge {
|
|||
#[allow(clippy::large_enum_variant)]
|
||||
pub(crate) enum Request {
|
||||
/// A request to fetch the metadata for a package.
|
||||
Package(PackageName, Option<IndexUrl>),
|
||||
Package(PackageName, Option<IndexMetadata>),
|
||||
/// A request to fetch the metadata for a built or source distribution.
|
||||
Dist(Dist),
|
||||
/// A request to fetch the metadata from an already-installed distribution.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ use std::sync::Arc;
|
|||
|
||||
use uv_configuration::BuildOptions;
|
||||
use uv_distribution::{ArchiveMetadata, DistributionDatabase, Reporter};
|
||||
use uv_distribution_types::{Dist, IndexCapabilities, IndexUrl, InstalledDist, RequestedDist};
|
||||
use uv_distribution_types::{
|
||||
Dist, IndexCapabilities, IndexMetadata, IndexMetadataRef, InstalledDist, RequestedDist,
|
||||
};
|
||||
use uv_normalize::PackageName;
|
||||
use uv_pep440::{Version, VersionSpecifiers};
|
||||
use uv_platform_tags::Tags;
|
||||
|
|
@ -78,7 +80,7 @@ pub trait ResolverProvider {
|
|||
fn get_package_versions<'io>(
|
||||
&'io self,
|
||||
package_name: &'io PackageName,
|
||||
index: Option<&'io IndexUrl>,
|
||||
index: Option<&'io IndexMetadata>,
|
||||
) -> impl Future<Output = PackageVersionsResult> + 'io;
|
||||
|
||||
/// Get the metadata for a distribution.
|
||||
|
|
@ -150,13 +152,18 @@ impl<Context: BuildContext> ResolverProvider for DefaultResolverProvider<'_, Con
|
|||
async fn get_package_versions<'io>(
|
||||
&'io self,
|
||||
package_name: &'io PackageName,
|
||||
index: Option<&'io IndexUrl>,
|
||||
index: Option<&'io IndexMetadata>,
|
||||
) -> PackageVersionsResult {
|
||||
let result = self
|
||||
.fetcher
|
||||
.client()
|
||||
.manual(|client, semaphore| {
|
||||
client.simple(package_name, index, self.capabilities, semaphore)
|
||||
client.simple(
|
||||
package_name,
|
||||
index.map(IndexMetadataRef::from),
|
||||
self.capabilities,
|
||||
semaphore,
|
||||
)
|
||||
})
|
||||
.await;
|
||||
|
||||
|
|
@ -171,7 +178,7 @@ impl<Context: BuildContext> ResolverProvider for DefaultResolverProvider<'_, Con
|
|||
VersionMap::from_metadata(
|
||||
metadata,
|
||||
package_name,
|
||||
index,
|
||||
index.url(),
|
||||
self.tags.as_ref(),
|
||||
&self.requires_python,
|
||||
&self.allowed_yanks,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use tokio::sync::Semaphore;
|
|||
use tracing::debug;
|
||||
use uv_client::{RegistryClient, VersionFiles};
|
||||
use uv_distribution_filename::DistFilename;
|
||||
use uv_distribution_types::{IndexCapabilities, IndexUrl};
|
||||
use uv_distribution_types::{IndexCapabilities, IndexMetadataRef, IndexUrl};
|
||||
use uv_normalize::PackageName;
|
||||
use uv_platform_tags::Tags;
|
||||
use uv_resolver::{ExcludeNewer, PrereleaseMode, RequiresPython};
|
||||
|
|
@ -34,7 +34,12 @@ impl LatestClient<'_> {
|
|||
|
||||
let archives = match self
|
||||
.client
|
||||
.simple(package, index, self.capabilities, download_concurrency)
|
||||
.simple(
|
||||
package,
|
||||
index.map(IndexMetadataRef::from),
|
||||
self.capabilities,
|
||||
download_concurrency,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(archives) => archives,
|
||||
|
|
|
|||
|
|
@ -1,17 +1,15 @@
|
|||
use crate::commands::reporters::PublishReporter;
|
||||
use crate::commands::{human_readable_bytes, ExitStatus};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::NetworkSettings;
|
||||
use anyhow::{bail, Context, Result};
|
||||
use console::Term;
|
||||
use owo_colors::OwoColorize;
|
||||
use std::fmt::Write;
|
||||
use std::iter;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::{bail, Context, Result};
|
||||
use console::Term;
|
||||
use owo_colors::OwoColorize;
|
||||
use tokio::sync::Semaphore;
|
||||
use tracing::{debug, info};
|
||||
use url::Url;
|
||||
|
||||
use uv_cache::Cache;
|
||||
use uv_client::{AuthIntegration, BaseClient, BaseClientBuilder, RegistryClientBuilder};
|
||||
use uv_configuration::{KeyringProviderType, TrustedPublishing};
|
||||
|
|
@ -21,6 +19,11 @@ use uv_publish::{
|
|||
};
|
||||
use uv_warnings::warn_user_once;
|
||||
|
||||
use crate::commands::reporters::PublishReporter;
|
||||
use crate::commands::{human_readable_bytes, ExitStatus};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::NetworkSettings;
|
||||
|
||||
pub(crate) async fn publish(
|
||||
paths: Vec<String>,
|
||||
publish_url: Url,
|
||||
|
|
|
|||
|
|
@ -15331,7 +15331,7 @@ fn lock_explicit_default_index() -> Result<()> {
|
|||
DEBUG No workspace root found, using project root
|
||||
DEBUG Ignoring existing lockfile due to mismatched requirements for: `project==0.1.0`
|
||||
Requested: {Requirement { name: PackageName("anyio"), extras: [], groups: [], marker: true, source: Registry { specifier: VersionSpecifiers([]), index: None, conflict: None }, origin: None }}
|
||||
Existing: {Requirement { name: PackageName("iniconfig"), extras: [], groups: [], marker: true, source: Registry { specifier: VersionSpecifiers([VersionSpecifier { operator: Equal, version: "2.0.0" }]), index: Some(Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("test.pypi.org")), port: None, path: "/simple", query: None, fragment: None }), conflict: None }, origin: None }}
|
||||
Existing: {Requirement { name: PackageName("iniconfig"), extras: [], groups: [], marker: true, source: Registry { specifier: VersionSpecifiers([VersionSpecifier { operator: Equal, version: "2.0.0" }]), index: Some(IndexMetadata { url: Url(VerbatimUrl { url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("test.pypi.org")), port: None, path: "/simple", query: None, fragment: None }, given: None }) }), conflict: None }, origin: None }}
|
||||
DEBUG Solving with installed Python version: 3.12.[X]
|
||||
DEBUG Solving with target Python version: >=3.12
|
||||
DEBUG Adding direct dependency: project*
|
||||
|
|
|
|||
Loading…
Reference in New Issue