mirror of https://github.com/astral-sh/uv
Add PEP 751 support to `uv pip compile` (#13019)
## Summary You now specify `--format pylock.toml` or `-o pylock.toml` to output in PEP 751 format.
This commit is contained in:
parent
b594c2d702
commit
2ba4edfbbe
|
|
@ -1075,13 +1075,22 @@ pub struct PipCompileArgs {
|
|||
#[arg(long, group = "sources")]
|
||||
pub group: Vec<PipGroupName>,
|
||||
|
||||
/// Write the compiled requirements to the given `requirements.txt` file.
|
||||
/// Write the compiled requirements to the given `requirements.txt` or `pylock.toml` file.
|
||||
///
|
||||
/// If the file already exists, the existing versions will be preferred when resolving
|
||||
/// dependencies, unless `--upgrade` is also specified.
|
||||
#[arg(long, short)]
|
||||
pub output_file: Option<PathBuf>,
|
||||
|
||||
/// The format in which the resolution should be output.
|
||||
///
|
||||
/// Supports both `requirements.txt` and `pylock.toml` (PEP 751) output formats.
|
||||
///
|
||||
/// uv will infer the output format from the file extension of the output file, if
|
||||
/// provided. Otherwise, defaults to `requirements.txt`.
|
||||
#[arg(long, value_enum)]
|
||||
pub format: Option<ExportFormat>,
|
||||
|
||||
/// Include extras in the output file.
|
||||
///
|
||||
/// By default, uv strips extras, as any packages pulled in by the extras are already included
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use uv_configuration::Upgrade;
|
|||
use uv_fs::CWD;
|
||||
use uv_git::ResolvedRepositoryReference;
|
||||
use uv_requirements_txt::RequirementsTxt;
|
||||
use uv_resolver::{Lock, LockError, Preference, PreferenceError};
|
||||
use uv_resolver::{Lock, LockError, Preference, PreferenceError, PylockToml, PylockTomlError};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct LockedRequirements {
|
||||
|
|
@ -17,9 +17,19 @@ pub struct LockedRequirements {
|
|||
pub git: Vec<ResolvedRepositoryReference>,
|
||||
}
|
||||
|
||||
impl LockedRequirements {
|
||||
/// Create a [`LockedRequirements`] from a list of preferences.
|
||||
pub fn from_preferences(preferences: Vec<Preference>) -> Self {
|
||||
Self {
|
||||
preferences,
|
||||
..LockedRequirements::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Load the preferred requirements from an existing `requirements.txt`, applying the upgrade strategy.
|
||||
pub async fn read_requirements_txt(
|
||||
output_file: Option<&Path>,
|
||||
output_file: &Path,
|
||||
upgrade: &Upgrade,
|
||||
) -> Result<Vec<Preference>> {
|
||||
// As an optimization, skip reading the lockfile is we're upgrading all packages anyway.
|
||||
|
|
@ -27,11 +37,6 @@ pub async fn read_requirements_txt(
|
|||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
// If the lockfile doesn't exist, don't respect any pinned versions.
|
||||
let Some(output_file) = output_file.filter(|path| path.exists()) else {
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
|
||||
// Parse the requirements from the lockfile.
|
||||
let requirements_txt = RequirementsTxt::parse(
|
||||
output_file,
|
||||
|
|
@ -95,3 +100,40 @@ pub fn read_lock_requirements(
|
|||
|
||||
Ok(LockedRequirements { preferences, git })
|
||||
}
|
||||
|
||||
/// Load the preferred requirements from an existing `pylock.toml` file, applying the upgrade strategy.
|
||||
pub async fn read_pylock_toml_requirements(
|
||||
output_file: &Path,
|
||||
upgrade: &Upgrade,
|
||||
) -> Result<LockedRequirements, PylockTomlError> {
|
||||
// As an optimization, skip iterating over the lockfile is we're upgrading all packages anyway.
|
||||
if upgrade.is_all() {
|
||||
return Ok(LockedRequirements::default());
|
||||
}
|
||||
|
||||
// Read the `pylock.toml` from disk, and deserialize it from TOML.
|
||||
let content = fs_err::tokio::read_to_string(&output_file).await?;
|
||||
let lock = toml::from_str::<PylockToml>(&content)?;
|
||||
|
||||
let mut preferences = Vec::new();
|
||||
let mut git = Vec::new();
|
||||
|
||||
for package in &lock.packages {
|
||||
// Skip the distribution if it's not included in the upgrade strategy.
|
||||
if upgrade.contains(&package.name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Map each entry in the lockfile to a preference.
|
||||
if let Some(preference) = Preference::from_pylock_toml(package)? {
|
||||
preferences.push(preference);
|
||||
}
|
||||
|
||||
// Map each entry in the lockfile to a Git SHA.
|
||||
if let Some(git_ref) = package.as_git_ref() {
|
||||
git.push(git_ref);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(LockedRequirements { preferences, git })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ pub use exclusions::Exclusions;
|
|||
pub use flat_index::{FlatDistributions, FlatIndex};
|
||||
pub use fork_strategy::ForkStrategy;
|
||||
pub use lock::{
|
||||
Installable, Lock, LockError, LockVersion, Package, PackageMap, PylockToml,
|
||||
Installable, Lock, LockError, LockVersion, Package, PackageMap, PylockToml, PylockTomlError,
|
||||
RequirementsTxtExport, ResolverManifest, SatisfiesResult, TreeDisplay, VERSION,
|
||||
};
|
||||
pub use manifest::Manifest;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ use uv_pep508::MarkerTree;
|
|||
use uv_pypi_types::ConflictItem;
|
||||
|
||||
use crate::graph_ops::{marker_reachability, Reachable};
|
||||
pub use crate::lock::export::pylock_toml::PylockToml;
|
||||
pub(crate) use crate::lock::export::pylock_toml::PylockTomlPackage;
|
||||
pub use crate::lock::export::pylock_toml::{PylockToml, PylockTomlError};
|
||||
pub use crate::lock::export::requirements_txt::RequirementsTxtExport;
|
||||
use crate::universal_marker::resolve_conflicts;
|
||||
use crate::{Installable, Package};
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use serde::Deserialize;
|
|||
use toml_edit::{value, Array, ArrayOfTables, Item, Table};
|
||||
use url::Url;
|
||||
|
||||
use uv_cache_key::RepositoryUrl;
|
||||
use uv_configuration::{DependencyGroupsWithDefaults, ExtrasSpecification, InstallOptions};
|
||||
use uv_distribution_filename::{
|
||||
BuildTag, DistExtension, ExtensionError, SourceDistExtension, SourceDistFilename,
|
||||
|
|
@ -18,11 +19,12 @@ use uv_distribution_filename::{
|
|||
};
|
||||
use uv_distribution_types::{
|
||||
BuiltDist, DirectUrlBuiltDist, DirectUrlSourceDist, DirectorySourceDist, Dist, Edge,
|
||||
FileLocation, GitSourceDist, IndexUrl, Node, PathBuiltDist, PathSourceDist, RegistryBuiltDist,
|
||||
RegistryBuiltWheel, RegistrySourceDist, RemoteSource, Resolution, ResolvedDist, SourceDist,
|
||||
ToUrlError, UrlString,
|
||||
FileLocation, GitSourceDist, IndexUrl, Name, Node, PathBuiltDist, PathSourceDist,
|
||||
RegistryBuiltDist, RegistryBuiltWheel, RegistrySourceDist, RemoteSource, Resolution,
|
||||
ResolvedDist, SourceDist, ToUrlError, UrlString,
|
||||
};
|
||||
use uv_fs::{relative_to, PortablePathBuf};
|
||||
use uv_git::{RepositoryReference, ResolvedRepositoryReference};
|
||||
use uv_git_types::{GitOid, GitReference, GitUrl, GitUrlParseError};
|
||||
use uv_normalize::{ExtraName, GroupName, PackageName};
|
||||
use uv_pep440::Version;
|
||||
|
|
@ -33,7 +35,8 @@ use uv_small_str::SmallString;
|
|||
|
||||
use crate::lock::export::ExportableRequirements;
|
||||
use crate::lock::{each_element_on_its_line_array, Source};
|
||||
use crate::{Installable, LockError, RequiresPython};
|
||||
use crate::resolution::ResolutionGraphNode;
|
||||
use crate::{Installable, LockError, RequiresPython, ResolverOutput};
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum PylockTomlError {
|
||||
|
|
@ -89,6 +92,10 @@ pub enum PylockTomlError {
|
|||
Extension(#[from] ExtensionError),
|
||||
#[error(transparent)]
|
||||
Jiff(#[from] jiff::Error),
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error(transparent)]
|
||||
Deserialize(#[from] toml::de::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
|
|
@ -105,17 +112,19 @@ pub struct PylockToml {
|
|||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
default_groups: Vec<GroupName>,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
packages: Vec<PylockTomlPackage>,
|
||||
pub packages: Vec<PylockTomlPackage>,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
attestation_identities: Vec<PylockTomlAttestationIdentity>,
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
struct PylockTomlPackage {
|
||||
name: PackageName,
|
||||
pub struct PylockTomlPackage {
|
||||
pub name: PackageName,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
version: Option<Version>,
|
||||
pub version: Option<Version>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub index: Option<Url>,
|
||||
#[serde(
|
||||
skip_serializing_if = "uv_pep508::marker::ser::is_empty",
|
||||
serialize_with = "uv_pep508::marker::ser::serialize",
|
||||
|
|
@ -127,8 +136,6 @@ struct PylockTomlPackage {
|
|||
#[serde(skip_serializing_if = "Vec::is_empty", default)]
|
||||
dependencies: Vec<PylockTomlDependency>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
index: Option<Url>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
vcs: Option<PylockTomlVcs>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
directory: Option<PylockTomlDirectory>,
|
||||
|
|
@ -239,6 +246,267 @@ struct PylockTomlAttestationIdentity {
|
|||
}
|
||||
|
||||
impl<'lock> PylockToml {
|
||||
/// Construct a [`PylockToml`] from a [`ResolverOutput`].
|
||||
pub fn from_resolution(
|
||||
resolution: &ResolverOutput,
|
||||
omit: &[PackageName],
|
||||
install_path: &Path,
|
||||
) -> Result<Self, PylockTomlError> {
|
||||
// The lock version is always `1.0` at time of writing.
|
||||
let lock_version = Version::new([1, 0]);
|
||||
|
||||
// The created by field is always `uv` at time of writing.
|
||||
let created_by = "uv".to_string();
|
||||
|
||||
// Use the `requires-python` from the target lockfile.
|
||||
let requires_python = resolution.requires_python.clone();
|
||||
|
||||
// We don't support locking for multiple extras at time of writing.
|
||||
let extras = vec![];
|
||||
|
||||
// We don't support locking for multiple dependency groups at time of writing.
|
||||
let dependency_groups = vec![];
|
||||
|
||||
// We don't support locking for multiple dependency groups at time of writing.
|
||||
let default_groups = vec![];
|
||||
|
||||
// We don't support attestation identities at time of writing.
|
||||
let attestation_identities = vec![];
|
||||
|
||||
// Convert each node to a `pylock.toml`-style package.
|
||||
let mut packages = Vec::with_capacity(resolution.graph.node_count());
|
||||
for node_index in resolution.graph.node_indices() {
|
||||
let ResolutionGraphNode::Dist(node) = &resolution.graph[node_index] else {
|
||||
continue;
|
||||
};
|
||||
if !node.is_base() {
|
||||
continue;
|
||||
}
|
||||
let ResolvedDist::Installable { dist, version } = &node.dist else {
|
||||
continue;
|
||||
};
|
||||
if omit.contains(dist.name()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create a `pylock.toml`-style package.
|
||||
let mut package = PylockTomlPackage {
|
||||
name: dist.name().clone(),
|
||||
version: version.clone(),
|
||||
marker: node.marker.pep508(),
|
||||
requires_python: None,
|
||||
dependencies: vec![],
|
||||
index: None,
|
||||
vcs: None,
|
||||
directory: None,
|
||||
archive: None,
|
||||
sdist: None,
|
||||
wheels: None,
|
||||
};
|
||||
|
||||
match &**dist {
|
||||
Dist::Built(BuiltDist::DirectUrl(dist)) => {
|
||||
package.archive = Some(PylockTomlArchive {
|
||||
url: Some((*dist.location).clone()),
|
||||
path: None,
|
||||
size: dist.size(),
|
||||
upload_time: None,
|
||||
subdirectory: None,
|
||||
hashes: Hashes::from(node.hashes.clone()),
|
||||
});
|
||||
}
|
||||
Dist::Built(BuiltDist::Path(dist)) => {
|
||||
let path = relative_to(&dist.install_path, install_path)
|
||||
.map(Box::<Path>::from)
|
||||
.unwrap_or_else(|_| dist.install_path.clone());
|
||||
package.archive = Some(PylockTomlArchive {
|
||||
url: None,
|
||||
path: Some(PortablePathBuf::from(path)),
|
||||
size: dist.size(),
|
||||
upload_time: None,
|
||||
subdirectory: None,
|
||||
hashes: Hashes::from(node.hashes.clone()),
|
||||
});
|
||||
}
|
||||
Dist::Built(BuiltDist::Registry(dist)) => {
|
||||
package.wheels = Some(
|
||||
dist.wheels
|
||||
.iter()
|
||||
.map(|wheel| {
|
||||
let url =
|
||||
wheel.file.url.to_url().map_err(PylockTomlError::ToUrl)?;
|
||||
Ok(PylockTomlWheel {
|
||||
// Optional "when the last component of path/ url would be the same value".
|
||||
name: if url
|
||||
.filename()
|
||||
.is_ok_and(|filename| filename == *wheel.file.filename)
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(wheel.filename.clone())
|
||||
},
|
||||
upload_time: wheel
|
||||
.file
|
||||
.upload_time_utc_ms
|
||||
.map(Timestamp::from_millisecond)
|
||||
.transpose()?,
|
||||
url: Some(
|
||||
wheel.file.url.to_url().map_err(PylockTomlError::ToUrl)?,
|
||||
),
|
||||
path: None,
|
||||
size: wheel.file.size,
|
||||
hashes: Hashes::from(wheel.file.hashes.clone()),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, PylockTomlError>>()?,
|
||||
);
|
||||
|
||||
if let Some(sdist) = dist.sdist.as_ref() {
|
||||
let url = sdist.file.url.to_url().map_err(PylockTomlError::ToUrl)?;
|
||||
package.sdist = Some(PylockTomlSdist {
|
||||
// Optional "when the last component of path/ url would be the same value".
|
||||
name: if url
|
||||
.filename()
|
||||
.is_ok_and(|filename| filename == *sdist.file.filename)
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(sdist.file.filename.clone())
|
||||
},
|
||||
upload_time: sdist
|
||||
.file
|
||||
.upload_time_utc_ms
|
||||
.map(Timestamp::from_millisecond)
|
||||
.transpose()?,
|
||||
url: Some(url),
|
||||
path: None,
|
||||
size: sdist.file.size,
|
||||
hashes: Hashes::from(sdist.file.hashes.clone()),
|
||||
});
|
||||
}
|
||||
}
|
||||
Dist::Source(SourceDist::DirectUrl(dist)) => {
|
||||
package.archive = Some(PylockTomlArchive {
|
||||
url: Some((*dist.location).clone()),
|
||||
path: None,
|
||||
size: dist.size(),
|
||||
upload_time: None,
|
||||
subdirectory: dist.subdirectory.clone().map(PortablePathBuf::from),
|
||||
hashes: Hashes::from(node.hashes.clone()),
|
||||
});
|
||||
}
|
||||
Dist::Source(SourceDist::Directory(dist)) => {
|
||||
let path = relative_to(&dist.install_path, install_path)
|
||||
.map(Box::<Path>::from)
|
||||
.unwrap_or_else(|_| dist.install_path.clone());
|
||||
package.directory = Some(PylockTomlDirectory {
|
||||
path: PortablePathBuf::from(path),
|
||||
editable: if dist.editable { Some(true) } else { None },
|
||||
subdirectory: None,
|
||||
});
|
||||
}
|
||||
Dist::Source(SourceDist::Git(dist)) => {
|
||||
package.vcs = Some(PylockTomlVcs {
|
||||
r#type: VcsKind::Git,
|
||||
url: Some(dist.git.repository().clone()),
|
||||
path: None,
|
||||
requested_revision: dist.git.reference().as_str().map(ToString::to_string),
|
||||
commit_id: dist.git.precise().unwrap_or_else(|| {
|
||||
panic!("Git distribution is missing a precise hash: {dist}")
|
||||
}),
|
||||
subdirectory: dist.subdirectory.clone().map(PortablePathBuf::from),
|
||||
});
|
||||
}
|
||||
Dist::Source(SourceDist::Path(dist)) => {
|
||||
let path = relative_to(&dist.install_path, install_path)
|
||||
.map(Box::<Path>::from)
|
||||
.unwrap_or_else(|_| dist.install_path.clone());
|
||||
package.archive = Some(PylockTomlArchive {
|
||||
url: None,
|
||||
path: Some(PortablePathBuf::from(path)),
|
||||
size: dist.size(),
|
||||
upload_time: None,
|
||||
subdirectory: None,
|
||||
hashes: Hashes::from(node.hashes.clone()),
|
||||
});
|
||||
}
|
||||
Dist::Source(SourceDist::Registry(dist)) => {
|
||||
package.wheels = Some(
|
||||
dist.wheels
|
||||
.iter()
|
||||
.map(|wheel| {
|
||||
let url =
|
||||
wheel.file.url.to_url().map_err(PylockTomlError::ToUrl)?;
|
||||
Ok(PylockTomlWheel {
|
||||
// Optional "when the last component of path/ url would be the same value".
|
||||
name: if url
|
||||
.filename()
|
||||
.is_ok_and(|filename| filename == *wheel.file.filename)
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(wheel.filename.clone())
|
||||
},
|
||||
upload_time: wheel
|
||||
.file
|
||||
.upload_time_utc_ms
|
||||
.map(Timestamp::from_millisecond)
|
||||
.transpose()?,
|
||||
url: Some(
|
||||
wheel.file.url.to_url().map_err(PylockTomlError::ToUrl)?,
|
||||
),
|
||||
path: None,
|
||||
size: wheel.file.size,
|
||||
hashes: Hashes::from(wheel.file.hashes.clone()),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, PylockTomlError>>()?,
|
||||
);
|
||||
|
||||
let url = dist.file.url.to_url().map_err(PylockTomlError::ToUrl)?;
|
||||
package.sdist = Some(PylockTomlSdist {
|
||||
// Optional "when the last component of path/ url would be the same value".
|
||||
name: if url
|
||||
.filename()
|
||||
.is_ok_and(|filename| filename == *dist.file.filename)
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(dist.file.filename.clone())
|
||||
},
|
||||
upload_time: dist
|
||||
.file
|
||||
.upload_time_utc_ms
|
||||
.map(Timestamp::from_millisecond)
|
||||
.transpose()?,
|
||||
url: Some(url),
|
||||
path: None,
|
||||
size: dist.file.size,
|
||||
hashes: Hashes::from(dist.file.hashes.clone()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Add the package to the list of packages.
|
||||
packages.push(package);
|
||||
}
|
||||
|
||||
// Sort the packages by name, then version.
|
||||
packages.sort_by(|a, b| a.name.cmp(&b.name).then(a.version.cmp(&b.version)));
|
||||
|
||||
// Return the constructed `pylock.toml`.
|
||||
Ok(PylockToml {
|
||||
lock_version,
|
||||
created_by,
|
||||
requires_python: Some(requires_python),
|
||||
extras,
|
||||
dependency_groups,
|
||||
default_groups,
|
||||
packages,
|
||||
attestation_identities,
|
||||
})
|
||||
}
|
||||
|
||||
/// Construct a [`PylockToml`] from a uv lockfile.
|
||||
pub fn from_lock(
|
||||
target: &impl Installable<'lock>,
|
||||
|
|
@ -258,7 +526,7 @@ impl<'lock> PylockToml {
|
|||
install_options,
|
||||
);
|
||||
|
||||
// Sort the nodes, such that unnamed URLs (editables) appear at the top.
|
||||
// Sort the nodes.
|
||||
nodes.sort_unstable_by_key(|node| &node.package.id);
|
||||
|
||||
// The lock version is always `1.0` at time of writing.
|
||||
|
|
@ -826,6 +1094,20 @@ impl PylockTomlPackage {
|
|||
|
||||
best.map(|(_, i)| i)
|
||||
}
|
||||
|
||||
/// Returns the [`ResolvedRepositoryReference`] for the package, if it is a Git source.
|
||||
pub fn as_git_ref(&self) -> Option<ResolvedRepositoryReference> {
|
||||
let vcs = self.vcs.as_ref()?;
|
||||
let url = vcs.url.as_ref()?;
|
||||
let requested_revision = vcs.requested_revision.as_ref()?;
|
||||
Some(ResolvedRepositoryReference {
|
||||
reference: RepositoryReference {
|
||||
url: RepositoryUrl::new(url),
|
||||
reference: GitReference::from_rev(requested_revision.clone()),
|
||||
},
|
||||
sha: vcs.commit_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl PylockTomlWheel {
|
||||
|
|
|
|||
|
|
@ -50,8 +50,9 @@ use uv_types::{BuildContext, HashStrategy};
|
|||
use uv_workspace::WorkspaceMember;
|
||||
|
||||
use crate::fork_strategy::ForkStrategy;
|
||||
pub use crate::lock::export::PylockToml;
|
||||
pub(crate) use crate::lock::export::PylockTomlPackage;
|
||||
pub use crate::lock::export::RequirementsTxtExport;
|
||||
pub use crate::lock::export::{PylockToml, PylockTomlError};
|
||||
pub use crate::lock::installable::Installable;
|
||||
pub use crate::lock::map::PackageMap;
|
||||
pub use crate::lock::tree::TreeDisplay;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ use tracing::trace;
|
|||
use uv_distribution_types::IndexUrl;
|
||||
use uv_normalize::PackageName;
|
||||
use uv_pep440::{Operator, Version};
|
||||
use uv_pep508::{MarkerTree, VersionOrUrl};
|
||||
use uv_pep508::{MarkerTree, VerbatimUrl, VersionOrUrl};
|
||||
use uv_pypi_types::{HashDigest, HashDigests, HashError};
|
||||
use uv_requirements_txt::{RequirementEntry, RequirementsTxtRequirement};
|
||||
|
||||
use crate::lock::PylockTomlPackage;
|
||||
use crate::universal_marker::UniversalMarker;
|
||||
use crate::{LockError, ResolverEnvironment};
|
||||
|
||||
|
|
@ -93,6 +94,27 @@ impl Preference {
|
|||
}))
|
||||
}
|
||||
|
||||
/// Create a [`Preference`] from a locked distribution.
|
||||
pub fn from_pylock_toml(package: &PylockTomlPackage) -> Result<Option<Self>, LockError> {
|
||||
let Some(version) = package.version.as_ref() else {
|
||||
return Ok(None);
|
||||
};
|
||||
Ok(Some(Self {
|
||||
name: package.name.clone(),
|
||||
version: version.clone(),
|
||||
marker: MarkerTree::TRUE,
|
||||
index: PreferenceIndex::from(
|
||||
package
|
||||
.index
|
||||
.as_ref()
|
||||
.map(|index| IndexUrl::from(VerbatimUrl::from(index.clone()))),
|
||||
),
|
||||
// `pylock.toml` doesn't have fork annotations.
|
||||
fork_markers: vec![],
|
||||
hashes: HashDigests::empty(),
|
||||
}))
|
||||
}
|
||||
|
||||
/// Return the [`PackageName`] of the package for this [`Preference`].
|
||||
pub fn name(&self) -> &PackageName {
|
||||
&self.name
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use std::path::PathBuf;
|
|||
use url::Url;
|
||||
|
||||
use uv_configuration::{
|
||||
ConfigSettings, IndexStrategy, KeyringProviderType, RequiredVersion, TargetTriple,
|
||||
TrustedPublishing,
|
||||
ConfigSettings, ExportFormat, IndexStrategy, KeyringProviderType, RequiredVersion,
|
||||
TargetTriple, TrustedPublishing,
|
||||
};
|
||||
use uv_distribution_types::{Index, IndexUrl, PipExtraIndex, PipFindLinks, PipIndex};
|
||||
use uv_install_wheel::LinkMode;
|
||||
|
|
@ -75,6 +75,7 @@ macro_rules! impl_combine_or {
|
|||
|
||||
impl_combine_or!(AnnotationStyle);
|
||||
impl_combine_or!(ExcludeNewer);
|
||||
impl_combine_or!(ExportFormat);
|
||||
impl_combine_or!(ForkStrategy);
|
||||
impl_combine_or!(Index);
|
||||
impl_combine_or!(IndexStrategy);
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ use uv_auth::UrlAuthPolicies;
|
|||
use uv_cache::Cache;
|
||||
use uv_client::{BaseClientBuilder, FlatIndexClient, RegistryClientBuilder};
|
||||
use uv_configuration::{
|
||||
BuildOptions, Concurrency, ConfigSettings, Constraints, ExtrasSpecification, IndexStrategy,
|
||||
NoBinary, NoBuild, PreviewMode, Reinstall, SourceStrategy, Upgrade,
|
||||
BuildOptions, Concurrency, ConfigSettings, Constraints, ExportFormat, ExtrasSpecification,
|
||||
IndexStrategy, NoBinary, NoBuild, PreviewMode, Reinstall, SourceStrategy, Upgrade,
|
||||
};
|
||||
use uv_configuration::{KeyringProviderType, TargetTriple};
|
||||
use uv_dispatch::{BuildDispatch, SharedState};
|
||||
|
|
@ -23,7 +23,8 @@ use uv_distribution_types::{
|
|||
DependencyMetadata, HashGeneration, Index, IndexLocations, NameRequirementSpecification,
|
||||
Origin, Requirement, UnresolvedRequirementSpecification, Verbatim,
|
||||
};
|
||||
use uv_fs::Simplified;
|
||||
use uv_fs::{Simplified, CWD};
|
||||
use uv_git::ResolvedRepositoryReference;
|
||||
use uv_install_wheel::LinkMode;
|
||||
use uv_normalize::{GroupName, PackageName};
|
||||
use uv_pypi_types::{Conflicts, SupportedEnvironments};
|
||||
|
|
@ -31,12 +32,13 @@ use uv_python::{
|
|||
EnvironmentPreference, PythonEnvironment, PythonInstallation, PythonPreference, PythonRequest,
|
||||
PythonVersion, VersionRequest,
|
||||
};
|
||||
use uv_requirements::upgrade::{read_pylock_toml_requirements, LockedRequirements};
|
||||
use uv_requirements::{
|
||||
upgrade::read_requirements_txt, RequirementsSource, RequirementsSpecification,
|
||||
};
|
||||
use uv_resolver::{
|
||||
AnnotationStyle, DependencyMode, DisplayResolutionGraph, ExcludeNewer, FlatIndex, ForkStrategy,
|
||||
InMemoryIndex, OptionsBuilder, PrereleaseMode, PythonRequirement, RequiresPython,
|
||||
InMemoryIndex, OptionsBuilder, PrereleaseMode, PylockToml, PythonRequirement, RequiresPython,
|
||||
ResolutionMode, ResolverEnvironment,
|
||||
};
|
||||
use uv_torch::{TorchMode, TorchStrategy};
|
||||
|
|
@ -64,6 +66,7 @@ pub(crate) async fn pip_compile(
|
|||
extras: ExtrasSpecification,
|
||||
groups: BTreeMap<PathBuf, Vec<GroupName>>,
|
||||
output_file: Option<&Path>,
|
||||
format: Option<ExportFormat>,
|
||||
resolution_mode: ResolutionMode,
|
||||
prerelease_mode: PrereleaseMode,
|
||||
fork_strategy: ForkStrategy,
|
||||
|
|
@ -118,15 +121,18 @@ pub(crate) async fn pip_compile(
|
|||
"uv pip compile".green()
|
||||
));
|
||||
}
|
||||
if output_file
|
||||
.and_then(Path::extension)
|
||||
.is_some_and(|name| name.eq_ignore_ascii_case("toml"))
|
||||
{
|
||||
return Err(anyhow!(
|
||||
"TOML is not a supported output format for `{}` (only `requirements.txt`-style output is supported)",
|
||||
"uv pip compile".green()
|
||||
));
|
||||
}
|
||||
|
||||
// Determine the output format.
|
||||
let format = format.unwrap_or_else(|| {
|
||||
let extension = output_file.and_then(Path::extension);
|
||||
if extension.is_some_and(|ext| ext.eq_ignore_ascii_case("txt")) {
|
||||
ExportFormat::RequirementsTxt
|
||||
} else if extension.is_some_and(|ext| ext.eq_ignore_ascii_case("toml")) {
|
||||
ExportFormat::PylockToml
|
||||
} else {
|
||||
ExportFormat::RequirementsTxt
|
||||
}
|
||||
});
|
||||
|
||||
// Respect `UV_PYTHON`
|
||||
if python.is_none() && python_version.is_none() {
|
||||
|
|
@ -334,8 +340,9 @@ pub(crate) async fn pip_compile(
|
|||
(Some(tags), ResolverEnvironment::specific(marker_env))
|
||||
};
|
||||
|
||||
// Generate, but don't enforce hashes for the requirements.
|
||||
let hasher = if generate_hashes {
|
||||
// Generate, but don't enforce hashes for the requirements. PEP 751 _requires_ a hash to be
|
||||
// present, but otherwise, we omit them by default.
|
||||
let hasher = if generate_hashes || matches!(format, ExportFormat::PylockToml) {
|
||||
HashStrategy::Generate(HashGeneration::All)
|
||||
} else {
|
||||
HashStrategy::None
|
||||
|
|
@ -396,7 +403,25 @@ pub(crate) async fn pip_compile(
|
|||
.build();
|
||||
|
||||
// Read the lockfile, if present.
|
||||
let preferences = read_requirements_txt(output_file, &upgrade).await?;
|
||||
let LockedRequirements { preferences, git } =
|
||||
if let Some(output_file) = output_file.filter(|output_file| output_file.exists()) {
|
||||
match format {
|
||||
ExportFormat::RequirementsTxt => LockedRequirements::from_preferences(
|
||||
read_requirements_txt(output_file, &upgrade).await?,
|
||||
),
|
||||
ExportFormat::PylockToml => {
|
||||
read_pylock_toml_requirements(output_file, &upgrade).await?
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LockedRequirements::default()
|
||||
};
|
||||
|
||||
// Populate the Git resolver.
|
||||
for ResolvedRepositoryReference { reference, sha } in git {
|
||||
debug!("Inserting Git reference into resolver: `{reference:?}` at `{sha}`");
|
||||
state.git().insert(reference, sha);
|
||||
}
|
||||
|
||||
// Combine the `--no-binary` and `--no-build` flags from the requirements files.
|
||||
let build_options = build_options.combine(no_binary, no_build);
|
||||
|
|
@ -524,96 +549,135 @@ pub(crate) async fn pip_compile(
|
|||
)?;
|
||||
}
|
||||
|
||||
if include_marker_expression {
|
||||
if let Some(marker_env) = resolver_env.marker_environment() {
|
||||
let relevant_markers = resolution.marker_tree(&top_level_index, marker_env)?;
|
||||
if let Some(relevant_markers) = relevant_markers.contents() {
|
||||
writeln!(
|
||||
writer,
|
||||
"{}",
|
||||
"# Pinned dependencies known to be valid for:".green()
|
||||
)?;
|
||||
writeln!(writer, "{}", format!("# {relevant_markers}").green())?;
|
||||
match format {
|
||||
ExportFormat::RequirementsTxt => {
|
||||
if include_marker_expression {
|
||||
if let Some(marker_env) = resolver_env.marker_environment() {
|
||||
let relevant_markers = resolution.marker_tree(&top_level_index, marker_env)?;
|
||||
if let Some(relevant_markers) = relevant_markers.contents() {
|
||||
writeln!(
|
||||
writer,
|
||||
"{}",
|
||||
"# Pinned dependencies known to be valid for:".green()
|
||||
)?;
|
||||
writeln!(writer, "{}", format!("# {relevant_markers}").green())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut wrote_preamble = false;
|
||||
let mut wrote_preamble = false;
|
||||
|
||||
// If necessary, include the `--index-url` and `--extra-index-url` locations.
|
||||
if include_index_url {
|
||||
if let Some(index) = index_locations.default_index() {
|
||||
writeln!(writer, "--index-url {}", index.url().verbatim())?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
let mut seen = FxHashSet::default();
|
||||
for extra_index in index_locations.implicit_indexes() {
|
||||
if seen.insert(extra_index.url()) {
|
||||
writeln!(writer, "--extra-index-url {}", extra_index.url().verbatim())?;
|
||||
wrote_preamble = true;
|
||||
// If necessary, include the `--index-url` and `--extra-index-url` locations.
|
||||
if include_index_url {
|
||||
if let Some(index) = index_locations.default_index() {
|
||||
writeln!(writer, "--index-url {}", index.url().verbatim())?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
let mut seen = FxHashSet::default();
|
||||
for extra_index in index_locations.implicit_indexes() {
|
||||
if seen.insert(extra_index.url()) {
|
||||
writeln!(writer, "--extra-index-url {}", extra_index.url().verbatim())?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If necessary, include the `--find-links` locations.
|
||||
if include_find_links {
|
||||
for flat_index in index_locations.flat_indexes() {
|
||||
writeln!(writer, "--find-links {}", flat_index.url().verbatim())?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If necessary, include the `--no-binary` and `--only-binary` options.
|
||||
if include_build_options {
|
||||
match build_options.no_binary() {
|
||||
NoBinary::None => {}
|
||||
NoBinary::All => {
|
||||
writeln!(writer, "--no-binary :all:")?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
NoBinary::Packages(packages) => {
|
||||
for package in packages {
|
||||
writeln!(writer, "--no-binary {package}")?;
|
||||
// If necessary, include the `--find-links` locations.
|
||||
if include_find_links {
|
||||
for flat_index in index_locations.flat_indexes() {
|
||||
writeln!(writer, "--find-links {}", flat_index.url().verbatim())?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
match build_options.no_build() {
|
||||
NoBuild::None => {}
|
||||
NoBuild::All => {
|
||||
writeln!(writer, "--only-binary :all:")?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
NoBuild::Packages(packages) => {
|
||||
for package in packages {
|
||||
writeln!(writer, "--only-binary {package}")?;
|
||||
wrote_preamble = true;
|
||||
|
||||
// If necessary, include the `--no-binary` and `--only-binary` options.
|
||||
if include_build_options {
|
||||
match build_options.no_binary() {
|
||||
NoBinary::None => {}
|
||||
NoBinary::All => {
|
||||
writeln!(writer, "--no-binary :all:")?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
NoBinary::Packages(packages) => {
|
||||
for package in packages {
|
||||
writeln!(writer, "--no-binary {package}")?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
match build_options.no_build() {
|
||||
NoBuild::None => {}
|
||||
NoBuild::All => {
|
||||
writeln!(writer, "--only-binary :all:")?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
NoBuild::Packages(packages) => {
|
||||
for package in packages {
|
||||
writeln!(writer, "--only-binary {package}")?;
|
||||
wrote_preamble = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we wrote an index, add a newline to separate it from the requirements
|
||||
if wrote_preamble {
|
||||
writeln!(writer)?;
|
||||
}
|
||||
|
||||
write!(
|
||||
writer,
|
||||
"{}",
|
||||
DisplayResolutionGraph::new(
|
||||
&resolution,
|
||||
&resolver_env,
|
||||
&no_emit_packages,
|
||||
generate_hashes,
|
||||
include_extras,
|
||||
include_markers || universal,
|
||||
include_annotations,
|
||||
include_index_annotation,
|
||||
annotation_style,
|
||||
)
|
||||
)?;
|
||||
}
|
||||
ExportFormat::PylockToml => {
|
||||
if include_marker_expression {
|
||||
warn_user!("The `--emit-marker-expression` option is not supported for `pylock.toml` output");
|
||||
}
|
||||
if include_index_url {
|
||||
warn_user!(
|
||||
"The `--emit-index-url` option is not supported for `pylock.toml` output"
|
||||
);
|
||||
}
|
||||
if include_find_links {
|
||||
warn_user!(
|
||||
"The `--emit-find-links` option is not supported for `pylock.toml` output"
|
||||
);
|
||||
}
|
||||
if include_build_options {
|
||||
warn_user!(
|
||||
"The `--emit-build-options` option is not supported for `pylock.toml` output"
|
||||
);
|
||||
}
|
||||
if include_index_annotation {
|
||||
warn_user!("The `--emit-index-annotation` option is not supported for `pylock.toml` output");
|
||||
}
|
||||
|
||||
// Determine the directory relative to which the output file should be written.
|
||||
let output_file = output_file.map(std::path::absolute).transpose()?;
|
||||
let install_path = if let Some(output_file) = output_file.as_deref() {
|
||||
output_file.parent().unwrap()
|
||||
} else {
|
||||
&*CWD
|
||||
};
|
||||
|
||||
// Convert the resolution to a `pylock.toml` file.
|
||||
let export = PylockToml::from_resolution(&resolution, &no_emit_packages, install_path)?;
|
||||
write!(writer, "{}", export.to_toml()?)?;
|
||||
}
|
||||
}
|
||||
|
||||
// If we wrote an index, add a newline to separate it from the requirements
|
||||
if wrote_preamble {
|
||||
writeln!(writer)?;
|
||||
}
|
||||
|
||||
write!(
|
||||
writer,
|
||||
"{}",
|
||||
DisplayResolutionGraph::new(
|
||||
&resolution,
|
||||
&resolver_env,
|
||||
&no_emit_packages,
|
||||
generate_hashes,
|
||||
include_extras,
|
||||
include_markers || universal,
|
||||
include_annotations,
|
||||
include_index_annotation,
|
||||
annotation_style,
|
||||
)
|
||||
)?;
|
||||
|
||||
// If any "unsafe" packages were excluded, notify the user.
|
||||
let excluded = no_emit_packages
|
||||
.into_iter()
|
||||
|
|
|
|||
|
|
@ -450,6 +450,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
args.settings.extras,
|
||||
groups,
|
||||
args.settings.output_file.as_deref(),
|
||||
args.format,
|
||||
args.settings.resolution,
|
||||
args.settings.prerelease,
|
||||
args.settings.fork_strategy,
|
||||
|
|
|
|||
|
|
@ -1638,6 +1638,7 @@ impl ExportSettings {
|
|||
#[allow(clippy::struct_excessive_bools)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct PipCompileSettings {
|
||||
pub(crate) format: Option<ExportFormat>,
|
||||
pub(crate) src_file: Vec<PathBuf>,
|
||||
pub(crate) constraints: Vec<PathBuf>,
|
||||
pub(crate) overrides: Vec<PathBuf>,
|
||||
|
|
@ -1666,6 +1667,7 @@ impl PipCompileSettings {
|
|||
deps,
|
||||
group,
|
||||
output_file,
|
||||
format,
|
||||
no_strip_extras,
|
||||
strip_extras,
|
||||
no_strip_markers,
|
||||
|
|
@ -1754,6 +1756,7 @@ impl PipCompileSettings {
|
|||
};
|
||||
|
||||
Self {
|
||||
format,
|
||||
src_file,
|
||||
constraints: constraints
|
||||
.into_iter()
|
||||
|
|
|
|||
|
|
@ -16254,18 +16254,973 @@ fn compile_invalid_output_file() -> Result<()> {
|
|||
error: `pyproject.toml` is not a supported output format for `uv pip compile` (only `requirements.txt`-style output is supported)
|
||||
");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_registry_wheel() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("iniconfig")?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.in")
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("uv.toml"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", upload-time = 2023-01-07T11:08:11Z, size = 4646, hashes = { sha256 = "2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", upload-time = 2023-01-07T11:08:09Z, size = 5892, hashes = { sha256 = "b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
"#);
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_sync()
|
||||
.arg("--preview")
|
||||
.arg("pylock.toml"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: TOML is not a supported output format for `uv pip compile` (only `requirements.txt`-style output is supported)
|
||||
");
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ iniconfig==2.0.0
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_registry_sdist() -> Result<()> {
|
||||
let context = TestContext::new("3.12").with_exclude_newer("2025-01-29T00:00:00Z");
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("source-distribution")?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "source-distribution"
|
||||
version = "0.0.3"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1f/e5/5b016c945d745f8b108e759d428341488a6aee8f51f07c6c4e33498bb91f/source_distribution-0.0.3.tar.gz", upload-time = 2024-11-03T02:35:36Z, size = 2166, hashes = { sha256 = "be5895c175dbca2d91709a6ab7d5f28e1794272db551ae9a5faf3ae2ed74c3d8" } }
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
"#);
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_sync()
|
||||
.arg("--preview")
|
||||
.arg("pylock.toml"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ source-distribution==0.0.3
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_directory() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
// Create a local dependency in a subdirectory.
|
||||
let pyproject_toml = context.temp_dir.child("foo").child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "1.0.0"
|
||||
dependencies = ["anyio"]
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
"#,
|
||||
)?;
|
||||
context
|
||||
.temp_dir
|
||||
.child("foo")
|
||||
.child("src")
|
||||
.child("foo")
|
||||
.child("__init__.py")
|
||||
.touch()?;
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("./foo")?;
|
||||
|
||||
let pyproject_toml = context.temp_dir.child("pyproject.toml");
|
||||
pyproject_toml.write_str(
|
||||
r#"
|
||||
[project]
|
||||
name = "project"
|
||||
version = "0.1.0"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["foo"]
|
||||
|
||||
[tool.uv.sources]
|
||||
foo = { path = "foo" }
|
||||
"#,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "anyio"
|
||||
version = "4.3.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", upload-time = 2024-02-19T08:36:28Z, size = 159642, hashes = { sha256 = "f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", upload-time = 2024-02-19T08:36:26Z, size = 85584, hashes = { sha256 = "048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "foo"
|
||||
version = "1.0.0"
|
||||
directory = { path = "foo" }
|
||||
|
||||
[[packages]]
|
||||
name = "idna"
|
||||
version = "3.6"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", upload-time = 2023-11-25T15:40:54Z, size = 175426, hashes = { sha256 = "9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", upload-time = 2023-11-25T15:40:52Z, size = 61567, hashes = { sha256 = "c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", upload-time = 2024-02-25T23:20:04Z, size = 20372, hashes = { sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", upload-time = 2024-02-25T23:20:01Z, size = 10235, hashes = { sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 4 packages in [TIME]
|
||||
"#);
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_sync()
|
||||
.arg("--preview")
|
||||
.arg("pylock.toml"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Prepared 4 packages in [TIME]
|
||||
Installed 4 packages in [TIME]
|
||||
+ anyio==4.3.0
|
||||
+ foo==1.0.0 (from file://[TEMP_DIR]/foo)
|
||||
+ idna==3.6
|
||||
+ sniffio==1.3.1
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "git")]
|
||||
fn pep_751_compile_git() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str(
|
||||
"uv-public-pypackage @ git+https://github.com/astral-test/uv-public-pypackage.git@0.0.1",
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "uv-public-pypackage"
|
||||
version = "0.1.0"
|
||||
vcs = { type = "git", url = "https://github.com/astral-test/uv-public-pypackage.git", requested-revision = "0.0.1", commit-id = "0dacfd662c64cb4ceb16e6cf65a157a8b715b979" }
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
"#);
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_sync()
|
||||
.arg("--preview")
|
||||
.arg("pylock.toml"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ uv-public-pypackage==0.1.0 (from git+https://github.com/astral-test/uv-public-pypackage.git@0dacfd662c64cb4ceb16e6cf65a157a8b715b979)
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_url_wheel() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str(
|
||||
"anyio @ https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl",
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "anyio"
|
||||
version = "4.3.0"
|
||||
archive = { url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", hashes = { sha256 = "048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8" } }
|
||||
|
||||
[[packages]]
|
||||
name = "idna"
|
||||
version = "3.6"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", upload-time = 2023-11-25T15:40:54Z, size = 175426, hashes = { sha256 = "9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", upload-time = 2023-11-25T15:40:52Z, size = 61567, hashes = { sha256 = "c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", upload-time = 2024-02-25T23:20:04Z, size = 20372, hashes = { sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", upload-time = 2024-02-25T23:20:01Z, size = 10235, hashes = { sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
"#);
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_sync()
|
||||
.arg("--preview")
|
||||
.arg("pylock.toml"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Prepared 2 packages in [TIME]
|
||||
Installed 3 packages in [TIME]
|
||||
+ anyio==4.3.0 (from https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl)
|
||||
+ idna==3.6
|
||||
+ sniffio==1.3.1
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_url_sdist() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str(
|
||||
"anyio @ https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz",
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "anyio"
|
||||
version = "4.3.0"
|
||||
archive = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", hashes = { sha256 = "f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" } }
|
||||
|
||||
[[packages]]
|
||||
name = "idna"
|
||||
version = "3.6"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", upload-time = 2023-11-25T15:40:54Z, size = 175426, hashes = { sha256 = "9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", upload-time = 2023-11-25T15:40:52Z, size = 61567, hashes = { sha256 = "c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", upload-time = 2024-02-25T23:20:04Z, size = 20372, hashes = { sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", upload-time = 2024-02-25T23:20:01Z, size = 10235, hashes = { sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
"#);
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_sync()
|
||||
.arg("--preview")
|
||||
.arg("pylock.toml"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Prepared 3 packages in [TIME]
|
||||
Installed 3 packages in [TIME]
|
||||
+ anyio==4.3.0 (from https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz)
|
||||
+ idna==3.6
|
||||
+ sniffio==1.3.1
|
||||
"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_path_wheel() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download the source.
|
||||
let archive = context.temp_dir.child("iniconfig-2.0.0-py3-none-any.whl");
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl",
|
||||
&archive,
|
||||
);
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("./iniconfig-2.0.0-py3-none-any.whl")?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
archive = { path = "iniconfig-2.0.0-py3-none-any.whl", hashes = { sha256 = "b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" } }
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
"#);
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_sync()
|
||||
.arg("--preview")
|
||||
.arg("pylock.toml"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Installed 1 package in [TIME]
|
||||
+ iniconfig==2.0.0 (from file://[TEMP_DIR]/iniconfig-2.0.0-py3-none-any.whl)
|
||||
"
|
||||
);
|
||||
|
||||
// Ensure that the path is relative to the output `pylock.toml` file.
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("nested/pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o nested/pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
archive = { path = "../iniconfig-2.0.0-py3-none-any.whl", hashes = { sha256 = "b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" } }
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
"#);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_path_sdist() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
// Download the source.
|
||||
let archive = context.temp_dir.child("iniconfig-2.0.0.tar.gz");
|
||||
download_to_disk(
|
||||
"https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz",
|
||||
&archive,
|
||||
);
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("./iniconfig-2.0.0.tar.gz")?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
archive = { path = "iniconfig-2.0.0.tar.gz", hashes = { sha256 = "2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3" } }
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
"#);
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_sync()
|
||||
.arg("--preview")
|
||||
.arg("pylock.toml"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ iniconfig==2.0.0 (from file://[TEMP_DIR]/iniconfig-2.0.0.tar.gz)
|
||||
"
|
||||
);
|
||||
|
||||
// Ensure that the path is relative to the output `pylock.toml` file.
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("nested/pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o nested/pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
archive = { path = "../iniconfig-2.0.0.tar.gz", hashes = { sha256 = "2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3" } }
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
"#);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_preferences() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str(indoc::indoc! {r"
|
||||
anyio==3.0.0
|
||||
idna==3.0.0
|
||||
"})?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "anyio"
|
||||
version = "3.0.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/99/0d/65165f99e5f4f3b4c43a5ed9db0fb7aa655f5a58f290727a30528a87eb45/anyio-3.0.0.tar.gz", upload-time = 2021-04-20T14:02:14Z, size = 116952, hashes = { sha256 = "b553598332c050af19f7d41f73a7790142f5bc3d5eb8bd82f5e515ec22019bd9" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/3b/49/ebee263b69fe243bd1fd0a88bc6bb0f7732bf1794ba3273cb446351f9482/anyio-3.0.0-py3-none-any.whl", upload-time = 2021-04-20T14:02:13Z, size = 72182, hashes = { sha256 = "e71c3d9d72291d12056c0265d07c6bbedf92332f78573e278aeb116f24f30395" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "idna"
|
||||
version = "3.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/2f/2e/bfe821bd26194fb474e0932df8ed82e24bd312ba628a8644d93c5a28b5d4/idna-3.0.tar.gz", upload-time = 2021-01-01T05:58:25Z, size = 180786, hashes = { sha256 = "c9a26e10e5558412384fac891eefb41957831d31be55f1e2c98ed97a70abb969" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/0f/6b/3a878f15ef3324754bf4780f8f047d692d9860be894ff8fb3135cef8bed8/idna-3.0-py2.py3-none-any.whl", upload-time = 2021-01-01T05:58:22Z, size = 58618, hashes = { sha256 = "320229aadbdfc597bc28876748cc0c9d04d476e0fe6caacaaddea146365d9f63" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", upload-time = 2024-02-25T23:20:04Z, size = 20372, hashes = { sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", upload-time = 2024-02-25T23:20:01Z, size = 10235, hashes = { sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
"#);
|
||||
|
||||
// Modify the requirements to loosen the `anyio` version.
|
||||
requirements_txt.write_str("anyio")?;
|
||||
|
||||
// The `anyio` version should be retained, since we respect the existing preferences.
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "anyio"
|
||||
version = "3.0.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/99/0d/65165f99e5f4f3b4c43a5ed9db0fb7aa655f5a58f290727a30528a87eb45/anyio-3.0.0.tar.gz", upload-time = 2021-04-20T14:02:14Z, size = 116952, hashes = { sha256 = "b553598332c050af19f7d41f73a7790142f5bc3d5eb8bd82f5e515ec22019bd9" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/3b/49/ebee263b69fe243bd1fd0a88bc6bb0f7732bf1794ba3273cb446351f9482/anyio-3.0.0-py3-none-any.whl", upload-time = 2021-04-20T14:02:13Z, size = 72182, hashes = { sha256 = "e71c3d9d72291d12056c0265d07c6bbedf92332f78573e278aeb116f24f30395" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "idna"
|
||||
version = "3.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/2f/2e/bfe821bd26194fb474e0932df8ed82e24bd312ba628a8644d93c5a28b5d4/idna-3.0.tar.gz", upload-time = 2021-01-01T05:58:25Z, size = 180786, hashes = { sha256 = "c9a26e10e5558412384fac891eefb41957831d31be55f1e2c98ed97a70abb969" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/0f/6b/3a878f15ef3324754bf4780f8f047d692d9860be894ff8fb3135cef8bed8/idna-3.0-py2.py3-none-any.whl", upload-time = 2021-01-01T05:58:22Z, size = 58618, hashes = { sha256 = "320229aadbdfc597bc28876748cc0c9d04d476e0fe6caacaaddea146365d9f63" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", upload-time = 2024-02-25T23:20:04Z, size = 20372, hashes = { sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", upload-time = 2024-02-25T23:20:01Z, size = 10235, hashes = { sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
"#);
|
||||
|
||||
// Unless we pass `--upgrade-package`.
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml")
|
||||
.arg("--upgrade-package")
|
||||
.arg("idna"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "anyio"
|
||||
version = "3.0.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/99/0d/65165f99e5f4f3b4c43a5ed9db0fb7aa655f5a58f290727a30528a87eb45/anyio-3.0.0.tar.gz", upload-time = 2021-04-20T14:02:14Z, size = 116952, hashes = { sha256 = "b553598332c050af19f7d41f73a7790142f5bc3d5eb8bd82f5e515ec22019bd9" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/3b/49/ebee263b69fe243bd1fd0a88bc6bb0f7732bf1794ba3273cb446351f9482/anyio-3.0.0-py3-none-any.whl", upload-time = 2021-04-20T14:02:13Z, size = 72182, hashes = { sha256 = "e71c3d9d72291d12056c0265d07c6bbedf92332f78573e278aeb116f24f30395" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "idna"
|
||||
version = "3.6"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", upload-time = 2023-11-25T15:40:54Z, size = 175426, hashes = { sha256 = "9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", upload-time = 2023-11-25T15:40:52Z, size = 61567, hashes = { sha256 = "c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", upload-time = 2024-02-25T23:20:04Z, size = 20372, hashes = { sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", upload-time = 2024-02-25T23:20:01Z, size = 10235, hashes = { sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
"#);
|
||||
|
||||
// Or `--upgrade`.
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml")
|
||||
.arg("--upgrade"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "anyio"
|
||||
version = "4.3.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", upload-time = 2024-02-19T08:36:28Z, size = 159642, hashes = { sha256 = "f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", upload-time = 2024-02-19T08:36:26Z, size = 85584, hashes = { sha256 = "048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "idna"
|
||||
version = "3.6"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/bf/3f/ea4b9117521a1e9c50344b909be7886dd00a519552724809bb1f486986c2/idna-3.6.tar.gz", upload-time = 2023-11-25T15:40:54Z, size = 175426, hashes = { sha256 = "9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/c2/e7/a82b05cf63a603df6e68d59ae6a68bf5064484a0718ea5033660af4b54a9/idna-3.6-py3-none-any.whl", upload-time = 2023-11-25T15:40:52Z, size = 61567, hashes = { sha256 = "c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", upload-time = 2024-02-25T23:20:04Z, size = 20372, hashes = { sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", upload-time = 2024-02-25T23:20:01Z, size = 10235, hashes = { sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
"#);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_warn() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("iniconfig")?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml")
|
||||
.arg("--emit-index-url"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml --emit-index-url
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", upload-time = 2023-01-07T11:08:11Z, size = 4646, hashes = { sha256 = "2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", upload-time = 2023-01-07T11:08:09Z, size = 5892, hashes = { sha256 = "b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
warning: The `--emit-index-url` option is not supported for `pylock.toml` output
|
||||
"#);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_non_universal() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("black")?;
|
||||
|
||||
// `colorama` should be excluded, since we're on Linux.
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--python-platform")
|
||||
.arg("linux")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --python-platform linux -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "black"
|
||||
version = "24.3.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8f/5f/bac24a952668c7482cfdb4ebf91ba57a796c9da8829363a772040c1a3312/black-24.3.0.tar.gz", upload-time = 2024-03-15T19:35:43Z, size = 634292, hashes = { sha256 = "a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f" } }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/32/1a25d1b83147ca128797a627f429f9dc390eb066805c6aa319bea3ffffa5/black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", upload-time = 2024-03-15T19:43:32Z, size = 1587891, hashes = { sha256 = "7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/91/6cb204786acc693edc4bf1b9230ffdc3cbfaeb7cd04d3a12fb4b13882a53/black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", upload-time = 2024-03-15T19:41:59Z, size = 1434886, hashes = { sha256 = "9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/e4/53b5d07117381f7d5e946a54dd4c62617faad90713649619bbc683769dfe/black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-03-15T19:38:22Z, size = 1747400, hashes = { sha256 = "e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/9c/f2e7532d11b05add5ab383a9f90be1a49954bf510803f98064b45b42f98e/black-24.3.0-cp310-cp310-win_amd64.whl", upload-time = 2024-03-15T19:39:43Z, size = 1363816, hashes = { sha256 = "4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/df/ceea5828be9c4931cb5a75b7e8fb02971f57524da7a16dfec0d4d575327f/black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", upload-time = 2024-03-15T19:45:27Z, size = 1571235, hashes = { sha256 = "4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/5f/30398c5056cb72f883b32b6520ad00042a9d0454b693f70509867db03a80/black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", upload-time = 2024-03-15T19:43:52Z, size = 1414926, hashes = { sha256 = "aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/59/498885b279e890f656ea4300a2671c964acb6d97994ea626479c2e5501b4/black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-03-15T19:38:13Z, size = 1725920, hashes = { sha256 = "65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/b0/4bef40c808cc615187db983b75bacdca1c110a229d41ba9887549fac529c/black-24.3.0-cp311-cp311-win_amd64.whl", upload-time = 2024-03-15T19:39:34Z, size = 1372608, hashes = { sha256 = "bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/c6/1d174efa9ff02b22d0124c73fc5f4d4fb006d0d9a081aadc354d05754a13/black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", upload-time = 2024-03-15T19:45:20Z, size = 1600822, hashes = { sha256 = "2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/ed/704731afffe460b8ff0672623b40fce9fe569f2ee617c15857e4d4440a3a/black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", upload-time = 2024-03-15T19:45:00Z, size = 1429987, hashes = { sha256 = "4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/05/8dd038e30caadab7120176d4bc109b7ca2f4457f12eef746b0560a583458/black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-03-15T19:38:24Z, size = 1755319, hashes = { sha256 = "c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/9d/e5fa1ff4ef1940be15a64883c0bb8d2fcf626efec996eab4ae5a8c691d2c/black-24.3.0-cp312-cp312-win_amd64.whl", upload-time = 2024-03-15T19:39:37Z, size = 1385180, hashes = { sha256 = "56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/76/1f85c4349d6b3424c7672dbc6c4b39ab89372b575801ffdc23d34b023c6f/black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", upload-time = 2024-03-15T19:47:26Z, size = 1579568, hashes = { sha256 = "79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/24/6d82cde63c1340ea55cb74fd697f62b94b6d6fa7069a1aa216475dfd2a30/black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", upload-time = 2024-03-15T19:46:18Z, size = 1423188, hashes = { sha256 = "e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/61/48664319cee4f8e22633e075ff101ec6253195b056cb23e0c5f8a5086e87/black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-03-15T19:38:15Z, size = 1730623, hashes = { sha256 = "65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/95/ed26a160d7a13d6afb3e94448ec079fb4e37bbedeaf408b6b6dbf67d6cd2/black-24.3.0-cp38-cp38-win_amd64.whl", upload-time = 2024-03-15T19:39:43Z, size = 1370465, hashes = { sha256 = "b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/f5/78881e9b1c340ccc02d5d4ebe61cfb9140452b3d11272a896b405033511b/black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", upload-time = 2024-03-15T19:48:33Z, size = 1587504, hashes = { sha256 = "c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/cc/67ba827fe23b39d55e8408937763b2ad21d904d63ca1c60b47d608ee7fb2/black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", upload-time = 2024-03-15T19:47:39Z, size = 1434037, hashes = { sha256 = "6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/aa/6a2493c7d3506e9b64edbd0782e21637c376da005eecc546904e47b5cdbf/black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-03-15T19:38:16Z, size = 1745481, hashes = { sha256 = "d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/68/9e86e73b58819624af6797ffe68dd7d09ed90fa1f9eb8d4d675f8c5e6ab0/black-24.3.0-cp39-cp39-win_amd64.whl", upload-time = 2024-03-15T19:39:15Z, size = 1363531, hashes = { sha256 = "7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/ea/31770a7e49f3eedfd8cd7b35e78b3a3aaad860400f8673994bc988318135/black-24.3.0-py3-none-any.whl", upload-time = 2024-03-15T19:35:41Z, size = 201493, hashes = { sha256 = "41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93" } },
|
||||
]
|
||||
|
||||
[[packages]]
|
||||
name = "click"
|
||||
version = "8.1.7"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", upload-time = 2023-08-17T17:29:11Z, size = 336121, hashes = { sha256 = "ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", upload-time = 2023-08-17T17:29:10Z, size = 97941, hashes = { sha256 = "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "mypy-extensions"
|
||||
version = "1.0.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", upload-time = 2023-02-04T12:11:27Z, size = 4433, hashes = { sha256 = "75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", upload-time = 2023-02-04T12:11:25Z, size = 4695, hashes = { sha256 = "4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "packaging"
|
||||
version = "24.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ee/b5/b43a27ac7472e1818c4bafd44430e69605baefe1f34440593e0332ec8b4d/packaging-24.0.tar.gz", upload-time = 2024-03-10T09:39:28Z, size = 147882, hashes = { sha256 = "eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", upload-time = 2024-03-10T09:39:25Z, size = 53488, hashes = { sha256 = "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "pathspec"
|
||||
version = "0.12.1"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", upload-time = 2023-12-10T22:30:45Z, size = 51043, hashes = { sha256 = "a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", upload-time = 2023-12-10T22:30:43Z, size = 31191, hashes = { sha256 = "a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "platformdirs"
|
||||
version = "4.2.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/96/dc/c1d911bf5bb0fdc58cc05010e9f3efe3b67970cef779ba7fbc3183b987a8/platformdirs-4.2.0.tar.gz", upload-time = 2024-01-31T01:00:36Z, size = 20055, hashes = { sha256 = "ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/55/72/4898c44ee9ea6f43396fbc23d9bfaf3d06e01b83698bdf2e4c919deceb7c/platformdirs-4.2.0-py3-none-any.whl", upload-time = 2024-01-31T01:00:34Z, size = 17717, hashes = { sha256 = "0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 6 packages in [TIME]
|
||||
"#);
|
||||
|
||||
// `colorama` should be included, since we're on Windows.
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--python-platform")
|
||||
.arg("windows")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --python-platform windows -o pylock.toml
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "black"
|
||||
version = "24.3.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8f/5f/bac24a952668c7482cfdb4ebf91ba57a796c9da8829363a772040c1a3312/black-24.3.0.tar.gz", upload-time = 2024-03-15T19:35:43Z, size = 634292, hashes = { sha256 = "a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f" } }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/32/1a25d1b83147ca128797a627f429f9dc390eb066805c6aa319bea3ffffa5/black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", upload-time = 2024-03-15T19:43:32Z, size = 1587891, hashes = { sha256 = "7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/91/6cb204786acc693edc4bf1b9230ffdc3cbfaeb7cd04d3a12fb4b13882a53/black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", upload-time = 2024-03-15T19:41:59Z, size = 1434886, hashes = { sha256 = "9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/e4/53b5d07117381f7d5e946a54dd4c62617faad90713649619bbc683769dfe/black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-03-15T19:38:22Z, size = 1747400, hashes = { sha256 = "e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/9c/f2e7532d11b05add5ab383a9f90be1a49954bf510803f98064b45b42f98e/black-24.3.0-cp310-cp310-win_amd64.whl", upload-time = 2024-03-15T19:39:43Z, size = 1363816, hashes = { sha256 = "4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/df/ceea5828be9c4931cb5a75b7e8fb02971f57524da7a16dfec0d4d575327f/black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", upload-time = 2024-03-15T19:45:27Z, size = 1571235, hashes = { sha256 = "4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/5f/30398c5056cb72f883b32b6520ad00042a9d0454b693f70509867db03a80/black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", upload-time = 2024-03-15T19:43:52Z, size = 1414926, hashes = { sha256 = "aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/59/498885b279e890f656ea4300a2671c964acb6d97994ea626479c2e5501b4/black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-03-15T19:38:13Z, size = 1725920, hashes = { sha256 = "65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/b0/4bef40c808cc615187db983b75bacdca1c110a229d41ba9887549fac529c/black-24.3.0-cp311-cp311-win_amd64.whl", upload-time = 2024-03-15T19:39:34Z, size = 1372608, hashes = { sha256 = "bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/c6/1d174efa9ff02b22d0124c73fc5f4d4fb006d0d9a081aadc354d05754a13/black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", upload-time = 2024-03-15T19:45:20Z, size = 1600822, hashes = { sha256 = "2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/ed/704731afffe460b8ff0672623b40fce9fe569f2ee617c15857e4d4440a3a/black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", upload-time = 2024-03-15T19:45:00Z, size = 1429987, hashes = { sha256 = "4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/05/8dd038e30caadab7120176d4bc109b7ca2f4457f12eef746b0560a583458/black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-03-15T19:38:24Z, size = 1755319, hashes = { sha256 = "c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/9d/e5fa1ff4ef1940be15a64883c0bb8d2fcf626efec996eab4ae5a8c691d2c/black-24.3.0-cp312-cp312-win_amd64.whl", upload-time = 2024-03-15T19:39:37Z, size = 1385180, hashes = { sha256 = "56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/76/1f85c4349d6b3424c7672dbc6c4b39ab89372b575801ffdc23d34b023c6f/black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", upload-time = 2024-03-15T19:47:26Z, size = 1579568, hashes = { sha256 = "79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/24/6d82cde63c1340ea55cb74fd697f62b94b6d6fa7069a1aa216475dfd2a30/black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", upload-time = 2024-03-15T19:46:18Z, size = 1423188, hashes = { sha256 = "e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/61/48664319cee4f8e22633e075ff101ec6253195b056cb23e0c5f8a5086e87/black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-03-15T19:38:15Z, size = 1730623, hashes = { sha256 = "65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/95/ed26a160d7a13d6afb3e94448ec079fb4e37bbedeaf408b6b6dbf67d6cd2/black-24.3.0-cp38-cp38-win_amd64.whl", upload-time = 2024-03-15T19:39:43Z, size = 1370465, hashes = { sha256 = "b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/f5/78881e9b1c340ccc02d5d4ebe61cfb9140452b3d11272a896b405033511b/black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", upload-time = 2024-03-15T19:48:33Z, size = 1587504, hashes = { sha256 = "c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/cc/67ba827fe23b39d55e8408937763b2ad21d904d63ca1c60b47d608ee7fb2/black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", upload-time = 2024-03-15T19:47:39Z, size = 1434037, hashes = { sha256 = "6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/aa/6a2493c7d3506e9b64edbd0782e21637c376da005eecc546904e47b5cdbf/black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", upload-time = 2024-03-15T19:38:16Z, size = 1745481, hashes = { sha256 = "d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/68/9e86e73b58819624af6797ffe68dd7d09ed90fa1f9eb8d4d675f8c5e6ab0/black-24.3.0-cp39-cp39-win_amd64.whl", upload-time = 2024-03-15T19:39:15Z, size = 1363531, hashes = { sha256 = "7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f" } },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/ea/31770a7e49f3eedfd8cd7b35e78b3a3aaad860400f8673994bc988318135/black-24.3.0-py3-none-any.whl", upload-time = 2024-03-15T19:35:41Z, size = 201493, hashes = { sha256 = "41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93" } },
|
||||
]
|
||||
|
||||
[[packages]]
|
||||
name = "click"
|
||||
version = "8.1.7"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", upload-time = 2023-08-17T17:29:11Z, size = 336121, hashes = { sha256 = "ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", upload-time = 2023-08-17T17:29:10Z, size = 97941, hashes = { sha256 = "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
marker = "sys_platform == 'win32'"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", upload-time = 2022-10-25T02:36:22Z, size = 27697, hashes = { sha256 = "08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", upload-time = 2022-10-25T02:36:20Z, size = 25335, hashes = { sha256 = "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "mypy-extensions"
|
||||
version = "1.0.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", upload-time = 2023-02-04T12:11:27Z, size = 4433, hashes = { sha256 = "75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", upload-time = 2023-02-04T12:11:25Z, size = 4695, hashes = { sha256 = "4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "packaging"
|
||||
version = "24.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ee/b5/b43a27ac7472e1818c4bafd44430e69605baefe1f34440593e0332ec8b4d/packaging-24.0.tar.gz", upload-time = 2024-03-10T09:39:28Z, size = 147882, hashes = { sha256 = "eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", upload-time = 2024-03-10T09:39:25Z, size = 53488, hashes = { sha256 = "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "pathspec"
|
||||
version = "0.12.1"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", upload-time = 2023-12-10T22:30:45Z, size = 51043, hashes = { sha256 = "a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", upload-time = 2023-12-10T22:30:43Z, size = 31191, hashes = { sha256 = "a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "platformdirs"
|
||||
version = "4.2.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/96/dc/c1d911bf5bb0fdc58cc05010e9f3efe3b67970cef779ba7fbc3183b987a8/platformdirs-4.2.0.tar.gz", upload-time = 2024-01-31T01:00:36Z, size = 20055, hashes = { sha256 = "ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/55/72/4898c44ee9ea6f43396fbc23d9bfaf3d06e01b83698bdf2e4c919deceb7c/platformdirs-4.2.0-py3-none-any.whl", upload-time = 2024-01-31T01:00:34Z, size = 17717, hashes = { sha256 = "0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068" } }]
|
||||
|
||||
----- stderr -----
|
||||
Resolved 7 packages in [TIME]
|
||||
"#);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pep_751_compile_no_emit_package() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let requirements_txt = context.temp_dir.child("requirements.txt");
|
||||
requirements_txt.write_str("anyio")?;
|
||||
|
||||
uv_snapshot!(context
|
||||
.pip_compile()
|
||||
.arg("requirements.txt")
|
||||
.arg("--universal")
|
||||
.arg("-o")
|
||||
.arg("pylock.toml")
|
||||
.arg("--no-emit-package")
|
||||
.arg("idna"), @r#"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile --cache-dir [CACHE_DIR] requirements.txt --universal -o pylock.toml --no-emit-package idna
|
||||
lock-version = "1.0"
|
||||
created-by = "uv"
|
||||
requires-python = ">=3.12.9"
|
||||
|
||||
[[packages]]
|
||||
name = "anyio"
|
||||
version = "4.3.0"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/db/4d/3970183622f0330d3c23d9b8a5f52e365e50381fd484d08e3285104333d3/anyio-4.3.0.tar.gz", upload-time = 2024-02-19T08:36:28Z, size = 159642, hashes = { sha256 = "f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/14/fd/2f20c40b45e4fb4324834aea24bd4afdf1143390242c0b33774da0e2e34f/anyio-4.3.0-py3-none-any.whl", upload-time = 2024-02-19T08:36:26Z, size = 85584, hashes = { sha256 = "048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8" } }]
|
||||
|
||||
[[packages]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", upload-time = 2024-02-25T23:20:04Z, size = 20372, hashes = { sha256 = "f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" } }
|
||||
wheels = [{ url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", upload-time = 2024-02-25T23:20:01Z, size = 10235, hashes = { sha256 = "2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" } }]
|
||||
|
||||
# The following packages were excluded from the output:
|
||||
# idna
|
||||
|
||||
----- stderr -----
|
||||
Resolved 3 packages in [TIME]
|
||||
"#);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -244,6 +245,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -405,6 +407,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -598,6 +601,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -760,6 +764,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -900,6 +905,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -1087,6 +1093,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -1280,6 +1287,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -1529,6 +1537,7 @@ fn resolve_find_links() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -1713,6 +1722,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -1858,6 +1868,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -2049,6 +2060,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -2263,6 +2275,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -2398,6 +2411,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -2533,6 +2547,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -2670,6 +2685,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -2990,6 +3006,7 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -3153,6 +3170,7 @@ fn resolve_both() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -3438,6 +3456,7 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -3699,6 +3718,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -3837,6 +3857,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -3994,6 +4015,7 @@ fn allow_insecure_host() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -4143,6 +4165,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -4336,6 +4359,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -4535,6 +4559,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -4729,6 +4754,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -4930,6 +4956,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
@ -5124,6 +5151,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
),
|
||||
}
|
||||
PipCompileSettings {
|
||||
format: None,
|
||||
src_file: [
|
||||
"requirements.in",
|
||||
],
|
||||
|
|
|
|||
|
|
@ -5723,6 +5723,19 @@ uv pip compile [OPTIONS] <SRC_FILE|--group <GROUP>>
|
|||
|
||||
<li><code>requires-python</code>: Optimize for selecting latest supported version of each package, for each supported Python version</li>
|
||||
</ul>
|
||||
</dd><dt id="uv-pip-compile--format"><a href="#uv-pip-compile--format"><code>--format</code></a> <i>format</i></dt><dd><p>The format in which the resolution should be output.</p>
|
||||
|
||||
<p>Supports both <code>requirements.txt</code> and <code>pylock.toml</code> (PEP 751) output formats.</p>
|
||||
|
||||
<p>uv will infer the output format from the file extension of the output file, if provided. Otherwise, defaults to <code>requirements.txt</code>.</p>
|
||||
|
||||
<p>Possible values:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>requirements.txt</code>: Export in <code>requirements.txt</code> format</li>
|
||||
|
||||
<li><code>pylock.toml</code>: Export in <code>pylock.toml</code> format</li>
|
||||
</ul>
|
||||
</dd><dt id="uv-pip-compile--generate-hashes"><a href="#uv-pip-compile--generate-hashes"><code>--generate-hashes</code></a></dt><dd><p>Include distribution hashes in the output file</p>
|
||||
|
||||
</dd><dt id="uv-pip-compile--group"><a href="#uv-pip-compile--group"><code>--group</code></a> <i>group</i></dt><dd><p>Install the specified dependency group from a <code>pyproject.toml</code>.</p>
|
||||
|
|
@ -5872,7 +5885,7 @@ uv pip compile [OPTIONS] <SRC_FILE|--group <GROUP>>
|
|||
|
||||
<p>Multiple packages may be provided. Disable binaries for all packages with <code>:all:</code>. Clear previously specified packages with <code>:none:</code>.</p>
|
||||
|
||||
</dd><dt id="uv-pip-compile--output-file"><a href="#uv-pip-compile--output-file"><code>--output-file</code></a>, <code>-o</code> <i>output-file</i></dt><dd><p>Write the compiled requirements to the given <code>requirements.txt</code> file.</p>
|
||||
</dd><dt id="uv-pip-compile--output-file"><a href="#uv-pip-compile--output-file"><code>--output-file</code></a>, <code>-o</code> <i>output-file</i></dt><dd><p>Write the compiled requirements to the given <code>requirements.txt</code> or <code>pylock.toml</code> file.</p>
|
||||
|
||||
<p>If the file already exists, the existing versions will be preferred when resolving dependencies, unless <code>--upgrade</code> is also specified.</p>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue