Apply first set of Rustfmt edition 2024 changes (#13478)

Rustfmt introduces a lot of formatting changes in the 2024 edition. To
not break everything all at once, we split out the set of formatting
changes compatible with both the 2021 and 2024 edition by first
formatting with the 2024 style, and then again with the currently used
2021 style.

Notable changes are the formatting of derive macro attributes and lines
with overly long strings and adding trailing semicolons after statements
consistently.
This commit is contained in:
konsti 2025-05-17 02:19:02 +02:00 committed by GitHub
parent b31d08c683
commit 5d37c7ecc5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
77 changed files with 660 additions and 313 deletions

View file

@ -245,7 +245,7 @@ fn find_module_root(
let dir = match fs_err::read_dir(src_root) {
Ok(dir_iterator) => dir_iterator.collect::<Result<Vec<_>, _>>()?,
Err(err) if err.kind() == io::ErrorKind::NotFound => {
return Err(Error::MissingSrc(src_root.to_path_buf()))
return Err(Error::MissingSrc(src_root.to_path_buf()));
}
Err(err) => return Err(Error::Io(err)),
};

View file

@ -30,9 +30,13 @@ pub(crate) const DEFAULT_EXCLUDES: &[&str] = &["__pycache__", "*.pyc", "*.pyo"];
pub enum ValidationError {
/// The spec isn't clear about what the values in that field would be, and we only support the
/// default value (UTF-8).
#[error("Charsets other than UTF-8 are not supported. Please convert your README to UTF-8 and remove `project.readme.charset`.")]
#[error(
"Charsets other than UTF-8 are not supported. Please convert your README to UTF-8 and remove `project.readme.charset`."
)]
ReadmeCharset,
#[error("Unknown Readme extension `{0}`, can't determine content type. Please use a support extension (`.md`, `.rst`, `.txt`) or set the content type manually.")]
#[error(
"Unknown Readme extension `{0}`, can't determine content type. Please use a support extension (`.md`, `.rst`, `.txt`) or set the content type manually."
)]
UnknownExtension(String),
#[error("Can't infer content type because `{}` does not have an extension. Please use a support extension (`.md`, `.rst`, `.txt`) or set the content type manually.", _0.user_display())]
MissingExtension(PathBuf),
@ -42,9 +46,13 @@ pub enum ValidationError {
DescriptionNewlines,
#[error("Dynamic metadata is not supported")]
Dynamic,
#[error("When `project.license-files` is defined, `project.license` must be an SPDX expression string")]
#[error(
"When `project.license-files` is defined, `project.license` must be an SPDX expression string"
)]
MixedLicenseGenerations,
#[error("Entrypoint groups must consist of letters and numbers separated by dots, invalid group: `{0}`")]
#[error(
"Entrypoint groups must consist of letters and numbers separated by dots, invalid group: `{0}`"
)]
InvalidGroup(String),
#[error(
"Entrypoint names must consist of letters, numbers, dots, underscores and dashes; invalid name: `{0}`"
@ -260,7 +268,7 @@ impl PyProjectToml {
Some("rst") => "text/x-rst",
Some("md") => "text/markdown",
Some(unknown) => {
return Err(ValidationError::UnknownExtension(unknown.to_owned()).into())
return Err(ValidationError::UnknownExtension(unknown.to_owned()).into());
}
None => return Err(ValidationError::MissingExtension(path.clone()).into()),
}
@ -388,7 +396,7 @@ impl PyProjectToml {
None => None,
Some(License::Spdx(license_expression)) => Some(license_expression.clone()),
Some(License::Text { .. } | License::File { .. }) => {
return Err(ValidationError::MixedLicenseGenerations.into())
return Err(ValidationError::MixedLicenseGenerations.into());
}
};

View file

@ -64,7 +64,9 @@ pub enum Error {
InvalidSourceDist(PathBuf),
#[error("Invalid `pyproject.toml`")]
InvalidPyprojectTomlSyntax(#[from] toml_edit::TomlError),
#[error("`pyproject.toml` does not match the required schema. When the `[project]` table is present, `project.name` must be present and non-empty.")]
#[error(
"`pyproject.toml` does not match the required schema. When the `[project]` table is present, `project.name` must be present and non-empty."
)]
InvalidPyprojectTomlSchema(#[from] toml_edit::de::Error),
#[error("Failed to resolve requirements from {0}")]
RequirementsResolve(&'static str, #[source] AnyErrorBuild),

View file

@ -948,7 +948,7 @@ async fn create_pep517_build_environment(
package_name,
package_version,
version_id,
))
));
}
};
@ -1098,7 +1098,7 @@ impl PythonRunner {
return Err(Error::CommandFailed(
venv.python_executable().to_path_buf(),
err,
))
));
}
}

View file

@ -273,9 +273,13 @@ mod tests {
// Two URLs should _not_ be considered equal if they request different subdirectories.
assert_ne!(
CanonicalUrl::parse("git+https://github.com/pypa/sample-namespace-packages.git#subdirectory=pkg_resources/pkg_a")?,
CanonicalUrl::parse("git+https://github.com/pypa/sample-namespace-packages.git#subdirectory=pkg_resources/pkg_b")?,
);
CanonicalUrl::parse(
"git+https://github.com/pypa/sample-namespace-packages.git#subdirectory=pkg_resources/pkg_a"
)?,
CanonicalUrl::parse(
"git+https://github.com/pypa/sample-namespace-packages.git#subdirectory=pkg_resources/pkg_b"
)?,
);
// Two URLs should _not_ be considered equal if they request different commit tags.
assert_ne!(
@ -353,9 +357,13 @@ mod tests {
// Two URLs should be considered equal if they map to the same repository, even if they
// request different subdirectories.
assert_eq!(
RepositoryUrl::parse("git+https://github.com/pypa/sample-namespace-packages.git#subdirectory=pkg_resources/pkg_a")?,
RepositoryUrl::parse("git+https://github.com/pypa/sample-namespace-packages.git#subdirectory=pkg_resources/pkg_b")?,
);
RepositoryUrl::parse(
"git+https://github.com/pypa/sample-namespace-packages.git#subdirectory=pkg_resources/pkg_a"
)?,
RepositoryUrl::parse(
"git+https://github.com/pypa/sample-namespace-packages.git#subdirectory=pkg_resources/pkg_b"
)?,
);
// Two URLs should be considered equal if they map to the same repository, even if they
// request different commit tags.

View file

@ -75,7 +75,9 @@ impl CompatArgs for PipCompileCompatArgs {
}
if self.no_allow_unsafe {
warn_user!("pip-compile's `--no-allow-unsafe` has no effect (uv can safely pin `pip` and other packages)");
warn_user!(
"pip-compile's `--no-allow-unsafe` has no effect (uv can safely pin `pip` and other packages)"
);
}
if self.reuse_hashes {

View file

@ -53,7 +53,9 @@ pub(crate) fn main(args: &Args) -> Result<()> {
println!("Up-to-date: {filename}");
} else {
let comparison = StrComparison::new(&current, &reference_string);
bail!("{filename} changed, please run `cargo dev generate-cli-reference`:\n{comparison}");
bail!(
"{filename} changed, please run `cargo dev generate-cli-reference`:\n{comparison}"
);
}
}
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {

View file

@ -34,7 +34,9 @@ pub(crate) fn main(args: &Args) -> anyhow::Result<()> {
anstream::println!("Up-to-date: {filename}");
} else {
let comparison = StrComparison::new(&current, &reference_string);
bail!("{filename} changed, please run `cargo dev generate-env-vars-reference`:\n{comparison}");
bail!(
"{filename} changed, please run `cargo dev generate-env-vars-reference`:\n{comparison}"
);
}
}
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
@ -60,7 +62,9 @@ pub(crate) fn main(args: &Args) -> anyhow::Result<()> {
fs_err::write(reference_path, reference_string.as_bytes())?;
}
Err(err) => {
bail!("{filename} changed, please run `cargo dev generate-env-vars-reference`:\n{err}");
bail!(
"{filename} changed, please run `cargo dev generate-env-vars-reference`:\n{err}"
);
}
},
}

View file

@ -47,7 +47,9 @@ pub(crate) fn main(args: &Args) -> Result<()> {
println!("Up-to-date: {filename}");
} else {
let comparison = StrComparison::new(&current, &schema_string);
bail!("{filename} changed, please run `cargo dev generate-json-schema`:\n{comparison}");
bail!(
"{filename} changed, please run `cargo dev generate-json-schema`:\n{comparison}"
);
}
}
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {

View file

@ -56,7 +56,9 @@ pub(crate) fn main(args: &Args) -> Result<()> {
println!("Up-to-date: {filename}");
} else {
let comparison = StrComparison::new(&current, &reference_string);
bail!("{filename} changed, please run `cargo dev generate-options-reference`:\n{comparison}");
bail!(
"{filename} changed, please run `cargo dev generate-options-reference`:\n{comparison}"
);
}
}
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
@ -68,25 +70,25 @@ pub(crate) fn main(args: &Args) -> Result<()> {
);
}
},
Mode::Write => {
match fs_err::read_to_string(&reference_path) {
Ok(current) => {
if current == reference_string {
println!("Up-to-date: {filename}");
} else {
println!("Updating: {filename}");
fs_err::write(reference_path, reference_string.as_bytes())?;
}
}
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
Mode::Write => match fs_err::read_to_string(&reference_path) {
Ok(current) => {
if current == reference_string {
println!("Up-to-date: {filename}");
} else {
println!("Updating: {filename}");
fs_err::write(reference_path, reference_string.as_bytes())?;
}
Err(err) => {
bail!("{filename} changed, please run `cargo dev generate-options-reference`:\n{err}");
}
}
}
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
println!("Updating: {filename}");
fs_err::write(reference_path, reference_string.as_bytes())?;
}
Err(err) => {
bail!(
"{filename} changed, please run `cargo dev generate-options-reference`:\n{err}"
);
}
},
}
Ok(())

View file

@ -117,8 +117,12 @@ impl Display for SourceDistExtension {
#[derive(Error, Debug)]
pub enum ExtensionError {
#[error("`.whl`, `.tar.gz`, `.zip`, `.tar.bz2`, `.tar.lz`, `.tar.lzma`, `.tar.xz`, `.tar.zst`, `.tar`, `.tbz`, `.tgz`, `.tlz`, or `.txz`")]
#[error(
"`.whl`, `.tar.gz`, `.zip`, `.tar.bz2`, `.tar.lz`, `.tar.lzma`, `.tar.xz`, `.tar.zst`, `.tar`, `.tbz`, `.tgz`, `.tlz`, or `.txz`"
)]
Dist,
#[error("`.tar.gz`, `.zip`, `.tar.bz2`, `.tar.lz`, `.tar.lzma`, `.tar.xz`, `.tar.zst`, `.tar`, `.tbz`, `.tgz`, `.tlz`, or `.txz`")]
#[error(
"`.tar.gz`, `.zip`, `.tar.bz2`, `.tar.lz`, `.tar.lzma`, `.tar.xz`, `.tar.zst`, `.tar`, `.tbz`, `.tgz`, `.tlz`, or `.txz`"
)]
SourceDist,
}

View file

@ -91,7 +91,9 @@ impl Deref for IndexName {
pub enum IndexNameError {
#[error("Index included a name, but the name was empty")]
EmptyName,
#[error("Index names may only contain letters, digits, hyphens, underscores, and periods, but found unsupported character (`{0}`) in: `{1}`")]
#[error(
"Index names may only contain letters, digits, hyphens, underscores, and periods, but found unsupported character (`{0}`) in: `{1}`"
)]
UnsupportedCharacter(char, String),
#[error("Index names must be ASCII, but found non-ASCII character (`{0}`) in: `{1}`")]
NonAsciiName(char, String),

View file

@ -146,7 +146,9 @@ impl Diagnostic for ResolutionDiagnostic {
format!("The package `{dist}` does not have an extra named `{extra}`")
}
Self::MissingDev { dist, dev } => {
format!("The package `{dist}` does not have a development dependency group named `{dev}`")
format!(
"The package `{dist}` does not have a development dependency group named `{dev}`"
)
}
Self::YankedVersion { dist, reason } => {
if let Some(reason) = reason {

View file

@ -465,7 +465,9 @@ impl<'a, Context: BuildContext> DistributionDatabase<'a, Context> {
Ok(ArchiveMetadata::from_metadata23(metadata))
}
Err(err) if err.is_http_streaming_unsupported() => {
warn!("Streaming unsupported when fetching metadata for {dist}; downloading wheel directly ({err})");
warn!(
"Streaming unsupported when fetching metadata for {dist}; downloading wheel directly ({err})"
);
// If the request failed due to an error that could be resolved by
// downloading the wheel directly, try that.

View file

@ -134,13 +134,17 @@ pub enum Error {
)]
MissingHashes { distribution: String },
#[error("Hash-checking is enabled, but no hashes were computed for: `{distribution}`\n\nExpected:\n{expected}")]
#[error(
"Hash-checking is enabled, but no hashes were computed for: `{distribution}`\n\nExpected:\n{expected}"
)]
MissingActualHashes {
distribution: String,
expected: String,
},
#[error("Hash-checking is enabled, but no hashes were provided for: `{distribution}`\n\nComputed:\n{actual}")]
#[error(
"Hash-checking is enabled, but no hashes were provided for: `{distribution}`\n\nComputed:\n{actual}"
)]
MissingExpectedHashes {
distribution: String,
actual: String,

View file

@ -504,11 +504,17 @@ impl LoweredRequirement {
/// `project.{dependencies,optional-dependencies}`.
#[derive(Debug, Error)]
pub enum LoweringError {
#[error("`{0}` is included as a workspace member, but is missing an entry in `tool.uv.sources` (e.g., `{0} = {{ workspace = true }}`)")]
#[error(
"`{0}` is included as a workspace member, but is missing an entry in `tool.uv.sources` (e.g., `{0} = {{ workspace = true }}`)"
)]
MissingWorkspaceSource(PackageName),
#[error("`{0}` is included as a workspace member, but references a {1} in `tool.uv.sources`. Workspace members must be declared as workspace sources (e.g., `{0} = {{ workspace = true }}`).")]
#[error(
"`{0}` is included as a workspace member, but references a {1} in `tool.uv.sources`. Workspace members must be declared as workspace sources (e.g., `{0} = {{ workspace = true }}`)."
)]
NonWorkspaceSource(PackageName, SourceKind),
#[error("`{0}` references a workspace in `tool.uv.sources` (e.g., `{0} = {{ workspace = true }}`), but is not a workspace member")]
#[error(
"`{0}` references a workspace in `tool.uv.sources` (e.g., `{0} = {{ workspace = true }}`), but is not a workspace member"
)]
UndeclaredWorkspacePackage(PackageName),
#[error("Can only specify one of: `rev`, `tag`, or `branch`")]
MoreThanOneGitRef,
@ -524,7 +530,9 @@ pub enum LoweringError {
InvalidVerbatimUrl(#[from] uv_pep508::VerbatimUrlError),
#[error("Fragments are not allowed in URLs: `{0}`")]
ForbiddenFragment(Url),
#[error("`{0}` is associated with a URL source, but references a Git repository. Consider using a Git source instead (e.g., `{0} = {{ git = \"{1}\" }}`)")]
#[error(
"`{0}` is associated with a URL source, but references a Git repository. Consider using a Git source instead (e.g., `{0} = {{ git = \"{1}\" }}`)"
)]
MissingGitSource(PackageName, Url),
#[error("`workspace = false` is not yet supported")]
WorkspaceFalse,
@ -532,7 +540,9 @@ pub enum LoweringError {
EditableFile(String),
#[error("Source with `package = true` must refer to a local directory, not a file: `{0}`")]
PackagedFile(String),
#[error("Git repository references local file source, but only directories are supported as transitive Git dependencies: `{0}`")]
#[error(
"Git repository references local file source, but only directories are supported as transitive Git dependencies: `{0}`"
)]
GitFile(String),
#[error(transparent)]
ParsedUrl(#[from] ParsedUrlError),
@ -622,7 +632,7 @@ fn url_source(
return Err(LoweringError::MissingGitSource(
requirement.name.clone(),
url.clone(),
))
));
}
Err(err) => {
return Err(ParsedUrlError::MissingExtensionUrl(url.to_string(), err).into());

View file

@ -30,13 +30,21 @@ pub enum MetadataError {
LoweringError(PackageName, #[source] Box<LoweringError>),
#[error("Failed to parse entry in group `{0}`: `{1}`")]
GroupLoweringError(GroupName, PackageName, #[source] Box<LoweringError>),
#[error("Source entry for `{0}` only applies to extra `{1}`, but the `{1}` extra does not exist. When an extra is present on a source (e.g., `extra = \"{1}\"`), the relevant package must be included in the `project.optional-dependencies` section for that extra (e.g., `project.optional-dependencies = {{ \"{1}\" = [\"{0}\"] }}`).")]
#[error(
"Source entry for `{0}` only applies to extra `{1}`, but the `{1}` extra does not exist. When an extra is present on a source (e.g., `extra = \"{1}\"`), the relevant package must be included in the `project.optional-dependencies` section for that extra (e.g., `project.optional-dependencies = {{ \"{1}\" = [\"{0}\"] }}`)."
)]
MissingSourceExtra(PackageName, ExtraName),
#[error("Source entry for `{0}` only applies to extra `{1}`, but `{0}` was not found under the `project.optional-dependencies` section for that extra. When an extra is present on a source (e.g., `extra = \"{1}\"`), the relevant package must be included in the `project.optional-dependencies` section for that extra (e.g., `project.optional-dependencies = {{ \"{1}\" = [\"{0}\"] }}`).")]
#[error(
"Source entry for `{0}` only applies to extra `{1}`, but `{0}` was not found under the `project.optional-dependencies` section for that extra. When an extra is present on a source (e.g., `extra = \"{1}\"`), the relevant package must be included in the `project.optional-dependencies` section for that extra (e.g., `project.optional-dependencies = {{ \"{1}\" = [\"{0}\"] }}`)."
)]
IncompleteSourceExtra(PackageName, ExtraName),
#[error("Source entry for `{0}` only applies to dependency group `{1}`, but the `{1}` group does not exist. When a group is present on a source (e.g., `group = \"{1}\"`), the relevant package must be included in the `dependency-groups` section for that extra (e.g., `dependency-groups = {{ \"{1}\" = [\"{0}\"] }}`).")]
#[error(
"Source entry for `{0}` only applies to dependency group `{1}`, but the `{1}` group does not exist. When a group is present on a source (e.g., `group = \"{1}\"`), the relevant package must be included in the `dependency-groups` section for that extra (e.g., `dependency-groups = {{ \"{1}\" = [\"{0}\"] }}`)."
)]
MissingSourceGroup(PackageName, GroupName),
#[error("Source entry for `{0}` only applies to dependency group `{1}`, but `{0}` was not found under the `dependency-groups` section for that group. When a group is present on a source (e.g., `group = \"{1}\"`), the relevant package must be included in the `dependency-groups` section for that extra (e.g., `dependency-groups = {{ \"{1}\" = [\"{0}\"] }}`).")]
#[error(
"Source entry for `{0}` only applies to dependency group `{1}`, but `{0}` was not found under the `dependency-groups` section for that group. When a group is present on a source (e.g., `group = \"{1}\"`), the relevant package must be included in the `dependency-groups` section for that extra (e.g., `dependency-groups = {{ \"{1}\" = [\"{0}\"] }}`)."
)]
IncompleteSourceGroup(PackageName, GroupName),
}

View file

@ -1620,7 +1620,9 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
// Nothing to do.
}
Err(err) => {
debug!("Failed to fetch `pyproject.toml` via GitHub fast path for: {source} ({err})");
debug!(
"Failed to fetch `pyproject.toml` via GitHub fast path for: {source} ({err})"
);
}
}
}
@ -2138,7 +2140,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
return Err(Error::Extract(
temp_dir.path().to_string_lossy().into_owned(),
err,
))
));
}
};
@ -2206,7 +2208,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
return Err(Error::Extract(
temp_dir.path().to_string_lossy().into_owned(),
err,
))
));
}
};

View file

@ -61,7 +61,7 @@ impl GitUrl {
return Err(GitUrlParseError::UnsupportedGitScheme(
unsupported.to_string(),
repository,
))
));
}
}
Ok(Self {

View file

@ -29,7 +29,9 @@ pub enum GitError {
GitNotFound,
#[error(transparent)]
Other(#[from] which::Error),
#[error("Remote Git fetches are not allowed because network connectivity is disabled (i.e., with `--offline`)")]
#[error(
"Remote Git fetches are not allowed because network connectivity is disabled (i.e., with `--offline`)"
)]
TransportNotAllowed,
}

View file

@ -237,7 +237,9 @@ fn clone_recursive(
} else {
synchronized_copy(&from, &to, locks)?;
}
warn_user_once!("Failed to clone files; falling back to full copy. This may lead to degraded performance.\n If the cache and target directories are on different filesystems, reflinking may not be supported.\n If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.");
warn_user_once!(
"Failed to clone files; falling back to full copy. This may lead to degraded performance.\n If the cache and target directories are on different filesystems, reflinking may not be supported.\n If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning."
);
}
}
@ -362,7 +364,9 @@ fn hardlink_wheel_files(
}
Attempt::UseCopyFallback => {
synchronized_copy(path, &out_path, locks)?;
warn_user_once!("Failed to hardlink files; falling back to full copy. This may lead to degraded performance.\n If the cache and target directories are on different filesystems, hardlinking may not be supported.\n If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.");
warn_user_once!(
"Failed to hardlink files; falling back to full copy. This may lead to degraded performance.\n If the cache and target directories are on different filesystems, hardlinking may not be supported.\n If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning."
);
}
}
@ -458,7 +462,9 @@ fn symlink_wheel_files(
}
Attempt::UseCopyFallback => {
synchronized_copy(path, &out_path, locks)?;
warn_user_once!("Failed to symlink files; falling back to full copy. This may lead to degraded performance.\n If the cache and target directories are on different filesystems, symlinking may not be supported.\n If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.");
warn_user_once!(
"Failed to symlink files; falling back to full copy. This may lead to degraded performance.\n If the cache and target directories are on different filesystems, symlinking may not be supported.\n If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning."
);
}
}

View file

@ -1089,9 +1089,14 @@ mod test {
);
// If the path is too long, we should not use the `exec` trick.
let executable = Path::new("/usr/bin/path/to/a/very/long/executable/executable/executable/executable/executable/executable/executable/executable/name/python3");
let executable = Path::new(
"/usr/bin/path/to/a/very/long/executable/executable/executable/executable/executable/executable/executable/executable/name/python3",
);
let os_name = "posix";
assert_eq!(format_shebang(executable, os_name, false), "#!/bin/sh\n'''exec' '/usr/bin/path/to/a/very/long/executable/executable/executable/executable/executable/executable/executable/executable/name/python3' \"$0\" \"$@\"\n' '''");
assert_eq!(
format_shebang(executable, os_name, false),
"#!/bin/sh\n'''exec' '/usr/bin/path/to/a/very/long/executable/executable/executable/executable/executable/executable/executable/executable/name/python3' \"$0\" \"$@\"\n' '''"
);
}
#[test]

View file

@ -99,7 +99,9 @@ impl<'a> Planner<'a> {
let source = RequirementSource::from(dist);
match RequirementSatisfaction::check(installed, &source) {
RequirementSatisfaction::Mismatch => {
debug!("Requirement installed, but mismatched:\n Installed: {installed:?}\n Requested: {source:?}");
debug!(
"Requirement installed, but mismatched:\n Installed: {installed:?}\n Requested: {source:?}"
);
}
RequirementSatisfaction::Satisfied => {
debug!("Requirement already installed: {installed}");
@ -203,11 +205,15 @@ impl<'a> Planner<'a> {
cached.push(CachedDist::Url(cached_dist));
continue;
}
debug!("Cached URL wheel requirement does not match expected hash policy for: {wheel}");
debug!(
"Cached URL wheel requirement does not match expected hash policy for: {wheel}"
);
}
Ok(None) => {}
Err(err) => {
debug!("Failed to deserialize cached URL wheel requirement for: {wheel} ({err})");
debug!(
"Failed to deserialize cached URL wheel requirement for: {wheel} ({err})"
);
}
}
}
@ -241,39 +247,43 @@ impl<'a> Planner<'a> {
.entry(format!("{}.rev", wheel.filename.cache_key()));
match LocalArchivePointer::read_from(&cache_entry) {
Ok(Some(pointer)) => {
match Timestamp::from_path(&wheel.install_path) {
Ok(timestamp) => {
if pointer.is_up_to_date(timestamp) {
let cache_info = pointer.to_cache_info();
let archive = pointer.into_archive();
if archive.satisfies(hasher.get(dist.as_ref())) {
let cached_dist = CachedDirectUrlDist {
filename: wheel.filename.clone(),
url: VerbatimParsedUrl {
parsed_url: wheel.parsed_url(),
verbatim: wheel.url.clone(),
},
hashes: archive.hashes,
cache_info,
path: cache.archive(&archive.id).into_boxed_path(),
};
Ok(Some(pointer)) => match Timestamp::from_path(&wheel.install_path) {
Ok(timestamp) => {
if pointer.is_up_to_date(timestamp) {
let cache_info = pointer.to_cache_info();
let archive = pointer.into_archive();
if archive.satisfies(hasher.get(dist.as_ref())) {
let cached_dist = CachedDirectUrlDist {
filename: wheel.filename.clone(),
url: VerbatimParsedUrl {
parsed_url: wheel.parsed_url(),
verbatim: wheel.url.clone(),
},
hashes: archive.hashes,
cache_info,
path: cache.archive(&archive.id).into_boxed_path(),
};
debug!("Path wheel requirement already cached: {cached_dist}");
cached.push(CachedDist::Url(cached_dist));
continue;
}
debug!("Cached path wheel requirement does not match expected hash policy for: {wheel}");
debug!(
"Path wheel requirement already cached: {cached_dist}"
);
cached.push(CachedDist::Url(cached_dist));
continue;
}
}
Err(err) => {
debug!("Failed to get timestamp for wheel {wheel} ({err})");
debug!(
"Cached path wheel requirement does not match expected hash policy for: {wheel}"
);
}
}
}
Err(err) => {
debug!("Failed to get timestamp for wheel {wheel} ({err})");
}
},
Ok(None) => {}
Err(err) => {
debug!("Failed to deserialize cached path wheel requirement for: {wheel} ({err})");
debug!(
"Failed to deserialize cached path wheel requirement for: {wheel} ({err})"
);
}
}
}
@ -315,8 +325,7 @@ impl<'a> Planner<'a> {
warn!(
"Cached wheel filename does not match requested distribution for: `{}` (found: `{}`)",
sdist,
wheel.filename
sdist, wheel.filename
);
}
Ok(None) => {}
@ -340,8 +349,7 @@ impl<'a> Planner<'a> {
warn!(
"Cached wheel filename does not match requested distribution for: `{}` (found: `{}`)",
sdist,
wheel.filename
sdist, wheel.filename
);
}
}
@ -364,8 +372,7 @@ impl<'a> Planner<'a> {
warn!(
"Cached wheel filename does not match requested distribution for: `{}` (found: `{}`)",
sdist,
wheel.filename
sdist, wheel.filename
);
}
Ok(None) => {}
@ -397,8 +404,7 @@ impl<'a> Planner<'a> {
warn!(
"Cached wheel filename does not match requested distribution for: `{}` (found: `{}`)",
sdist,
wheel.filename
sdist, wheel.filename
);
}
Ok(None) => {}

View file

@ -309,7 +309,7 @@ impl SitePackages {
[] => {
return Ok(SatisfiesResult::Unsatisfied(
requirement.url.verbatim.raw().to_string(),
))
));
}
[distribution] => {
let requirement = uv_pep508::Requirement {
@ -326,7 +326,7 @@ impl SitePackages {
_ => {
return Ok(SatisfiesResult::Unsatisfied(
requirement.url.verbatim.raw().to_string(),
))
));
}
}
}
@ -349,7 +349,7 @@ impl SitePackages {
[] => {
return Ok(SatisfiesResult::Unsatisfied(
requirement.url.verbatim.raw().to_string(),
))
));
}
[distribution] => {
let requirement = uv_pep508::Requirement {
@ -366,7 +366,7 @@ impl SitePackages {
_ => {
return Ok(SatisfiesResult::Unsatisfied(
requirement.url.verbatim.raw().to_string(),
))
));
}
}
}
@ -447,7 +447,7 @@ impl SitePackages {
RequirementSatisfaction::Mismatch
| RequirementSatisfaction::OutOfDate
| RequirementSatisfaction::CacheInvalid => {
return Ok(SatisfiesResult::Unsatisfied(requirement.to_string()))
return Ok(SatisfiesResult::Unsatisfied(requirement.to_string()));
}
RequirementSatisfaction::Satisfied => {}
}
@ -462,7 +462,7 @@ impl SitePackages {
| RequirementSatisfaction::CacheInvalid => {
return Ok(SatisfiesResult::Unsatisfied(
requirement.to_string(),
))
));
}
RequirementSatisfaction::Satisfied => {}
}
@ -572,7 +572,8 @@ impl Diagnostic for SitePackagesDiagnostic {
fn message(&self) -> String {
match self {
Self::MetadataUnavailable { package, path } => format!(
"The package `{package}` is broken or incomplete (unable to read `METADATA`). Consider recreating the virtualenv, or removing the package directory at: {}.", path.display(),
"The package `{package}` is broken or incomplete (unable to read `METADATA`). Consider recreating the virtualenv, or removing the package directory at: {}.",
path.display(),
),
Self::IncompatiblePythonVersion {
package,
@ -599,7 +600,8 @@ impl Diagnostic for SitePackagesDiagnostic {
paths.sort();
format!(
"The package `{package}` has multiple installed distributions: {}",
paths.iter().fold(String::new(), |acc, path| acc + &format!("\n - {}", path.display()))
paths.iter().fold(String::new(), |acc, path| acc
+ &format!("\n - {}", path.display()))
)
}
}

View file

@ -26,7 +26,9 @@ pub async fn uninstall(
#[derive(thiserror::Error, Debug)]
pub enum UninstallError {
#[error("Unable to uninstall `{0}`. distutils-installed distributions do not include the metadata required to uninstall safely.")]
#[error(
"Unable to uninstall `{0}`. distutils-installed distributions do not include the metadata required to uninstall safely."
)]
Distutils(InstalledEggInfoFile),
#[error(transparent)]
Uninstall(#[from] uv_install_wheel::Error),

View file

@ -94,7 +94,9 @@ impl VersionSpecifiers {
}
_ => {
#[cfg(feature = "tracing")]
warn!("Ignoring unsupported gap in `requires-python` version: {next:?} -> {lower:?}");
warn!(
"Ignoring unsupported gap in `requires-python` version: {next:?} -> {lower:?}"
);
}
}
next = upper;

View file

@ -569,9 +569,9 @@ fn parse_extras_cursor<T: Pep508Url>(
}
(Some((pos, other)), false) => {
return Err(Pep508Error {
message: Pep508ErrorSource::String(
format!("Expected either `,` (separating extras) or `]` (ending the extras section), found `{other}`")
),
message: Pep508ErrorSource::String(format!(
"Expected either `,` (separating extras) or `]` (ending the extras section), found `{other}`"
)),
start: pos,
len: 1,
input: cursor.to_string(),
@ -1120,7 +1120,10 @@ mod tests {
#[cfg(feature = "non-pep508-extensions")]
fn direct_url_no_extras() {
let numpy = crate::UnnamedRequirement::<VerbatimUrl>::from_str("https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl").unwrap();
assert_eq!(numpy.url.to_string(), "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl");
assert_eq!(
numpy.url.to_string(),
"https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl"
);
assert_eq!(*numpy.extras, []);
}

View file

@ -2000,7 +2000,7 @@ mod test {
let string_string = MarkerTree::from_str("'b' >= 'a'").unwrap();
string_string.evaluate(&env37, &[]);
logs_contain(
"Comparing two quoted strings with each other doesn't make sense: 'b' >= 'a', will evaluate to false"
"Comparing two quoted strings with each other doesn't make sense: 'b' >= 'a', will evaluate to false",
);
}
@ -2016,13 +2016,13 @@ mod test {
.iter()
.map(|s| s.split_once(" ").unwrap().1)
.collect();
let expected = [
let expected = [
"WARN warnings4: uv_pep508: os.name is deprecated in favor of os_name",
"WARN warnings4: uv_pep508: platform.machine is deprecated in favor of platform_machine",
"WARN warnings4: uv_pep508: platform.python_implementation is deprecated in favor of platform_python_implementation",
"WARN warnings4: uv_pep508: platform.version is deprecated in favor of platform_version",
"WARN warnings4: uv_pep508: sys.platform is deprecated in favor of sys_platform",
"WARN warnings4: uv_pep508: Comparing linux and posix lexicographically"
"WARN warnings4: uv_pep508: Comparing linux and posix lexicographically",
];
if lines == expected {
Ok(())

View file

@ -108,15 +108,21 @@ pub enum PublishSendError {
StatusNoBody(StatusCode, #[source] reqwest::Error),
#[error("Upload failed with status code {0}. Server says: {1}")]
Status(StatusCode, String),
#[error("POST requests are not supported by the endpoint, are you using the simple index URL instead of the upload URL?")]
#[error(
"POST requests are not supported by the endpoint, are you using the simple index URL instead of the upload URL?"
)]
MethodNotAllowedNoBody,
#[error("POST requests are not supported by the endpoint, are you using the simple index URL instead of the upload URL? Server says: {0}")]
#[error(
"POST requests are not supported by the endpoint, are you using the simple index URL instead of the upload URL? Server says: {0}"
)]
MethodNotAllowed(String),
/// The registry returned a "403 Forbidden".
#[error("Permission denied (status code {0}): {1}")]
PermissionDenied(StatusCode, String),
/// See inline comment.
#[error("The request was redirected, but redirects are not allowed when publishing, please use the canonical URL: `{0}`")]
#[error(
"The request was redirected, but redirects are not allowed when publishing, please use the canonical URL: `{0}`"
)]
RedirectError(Url),
}
@ -319,7 +325,9 @@ pub async fn check_trusted_publishing(
}
// We could check for credentials from the keyring or netrc the auth middleware first, but
// given that we are in GitHub Actions we check for trusted publishing first.
debug!("Running on GitHub Actions without explicit credentials, checking for trusted publishing");
debug!(
"Running on GitHub Actions without explicit credentials, checking for trusted publishing"
);
match trusted_publishing::get_token(registry, client.for_host(registry)).await {
Ok(token) => Ok(TrustedPublishResult::Configured(token)),
Err(err) => {
@ -1010,8 +1018,7 @@ mod tests {
/// Snapshot the data we send for an upload request for a wheel.
#[tokio::test]
async fn upload_request_wheel() {
let raw_filename =
"tqdm-4.66.1-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl";
let raw_filename = "tqdm-4.66.1-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl";
let file = PathBuf::from("../../scripts/links/").join(raw_filename);
let filename = DistFilename::try_from_normalized_filename(raw_filename).unwrap();

View file

@ -182,7 +182,7 @@ impl ResolutionMetadata {
match field.as_str() {
"dependencies" => return Err(MetadataError::DynamicField("dependencies")),
"optional-dependencies" => {
return Err(MetadataError::DynamicField("optional-dependencies"))
return Err(MetadataError::DynamicField("optional-dependencies"));
}
"requires-python" => return Err(MetadataError::DynamicField("requires-python")),
// When building from a source distribution, the version is known from the filename and

View file

@ -36,7 +36,9 @@ pub enum MetadataError {
InvalidPyprojectTomlSyntax(#[source] toml_edit::TomlError),
#[error(transparent)]
InvalidPyprojectTomlSchema(toml_edit::de::Error),
#[error("`pyproject.toml` is using the `[project]` table, but the required `project.name` field is not set")]
#[error(
"`pyproject.toml` is using the `[project]` table, but the required `project.name` field is not set"
)]
MissingName,
#[error("Metadata field {0} not found")]
FieldNotFound(&'static str),
@ -54,7 +56,9 @@ pub enum MetadataError {
UnsupportedMetadataVersion(String),
#[error("The following field was marked as dynamic: {0}")]
DynamicField(&'static str),
#[error("The project uses Poetry's syntax to declare its dependencies, despite including a `project` table in `pyproject.toml`")]
#[error(
"The project uses Poetry's syntax to declare its dependencies, despite including a `project` table in `pyproject.toml`"
)]
PoetrySyntax,
#[error("Failed to read `requires.txt` contents")]
RequiresTxtContents(#[from] std::io::Error),

View file

@ -41,7 +41,7 @@ impl RequiresDist {
match field.as_str() {
"dependencies" => return Err(MetadataError::DynamicField("dependencies")),
"optional-dependencies" => {
return Err(MetadataError::DynamicField("optional-dependencies"))
return Err(MetadataError::DynamicField("optional-dependencies"));
}
"version" => {
dynamic = true;

View file

@ -28,7 +28,9 @@ pub enum ParsedUrlError {
UrlParse(String, #[source] ParseError),
#[error(transparent)]
VerbatimUrl(#[from] VerbatimUrlError),
#[error("Direct URL (`{0}`) references a Git repository, but is missing the `git+` prefix (e.g., `git+{0}`)")]
#[error(
"Direct URL (`{0}`) references a Git repository, but is missing the `git+` prefix (e.g., `git+{0}`)"
)]
MissingGitPrefix(String),
#[error("Expected direct URL (`{0}`) to end in a supported file extension: {1}")]
MissingExtensionUrl(String, ExtensionError),
@ -309,7 +311,7 @@ impl TryFrom<Url> for ParsedArchiveUrl {
let ext = match DistExtension::from_path(url.path()) {
Ok(ext) => ext,
Err(..) if looks_like_git_repository(&url) => {
return Err(ParsedUrlError::MissingGitPrefix(url.to_string()))
return Err(ParsedUrlError::MissingGitPrefix(url.to_string()));
}
Err(err) => return Err(ParsedUrlError::MissingExtensionUrl(url.to_string(), err)),
};

View file

@ -94,7 +94,9 @@ pub enum Error {
Mirror(&'static str, &'static str),
#[error(transparent)]
LibcDetection(#[from] LibcDetectionError),
#[error("Remote python downloads JSON is not yet supported, please use a local path (without `file://` prefix)")]
#[error(
"Remote python downloads JSON is not yet supported, please use a local path (without `file://` prefix)"
)]
RemoteJSONNotSupported(),
#[error("The json of the python downloads is invalid: {0}")]
InvalidPythonDownloadsJSON(String, #[source] serde_json::Error),
@ -401,7 +403,9 @@ impl From<&ManagedPythonInstallation> for PythonDownloadRequest {
Some(VersionRequest::from(&key.version())),
match &key.implementation {
LenientImplementationName::Known(implementation) => Some(*implementation),
LenientImplementationName::Unknown(name) => unreachable!("Managed Python installations are expected to always have known implementation names, found {name}"),
LenientImplementationName::Unknown(name) => unreachable!(
"Managed Python installations are expected to always have known implementation names, found {name}"
),
},
Some(key.arch),
Some(key.os),

View file

@ -106,8 +106,15 @@ impl fmt::Display for EnvironmentNotFound {
match search_type {
// This error message assumes that the relevant API accepts the `--system` flag. This
// is true of the callsites today, since the project APIs never surface this error.
SearchType::Virtual => write!(f, "; run `{}` to create an environment, or pass `{}` to install into a non-virtual environment", "uv venv".green(), "--system".green())?,
SearchType::VirtualOrSystem => write!(f, "; run `{}` to create an environment", "uv venv".green())?,
SearchType::Virtual => write!(
f,
"; run `{}` to create an environment, or pass `{}` to install into a non-virtual environment",
"uv venv".green(),
"--system".green()
)?,
SearchType::VirtualOrSystem => {
write!(f, "; run `{}` to create an environment", "uv venv".green())?;
}
SearchType::System => {}
}

View file

@ -740,7 +740,9 @@ enum InterpreterInfoResult {
pub enum InterpreterInfoError {
#[error("Could not detect a glibc or a musl libc (while running on Linux)")]
LibcNotFound,
#[error("Broken Python installation, `platform.mac_ver()` returned an empty value, please reinstall Python")]
#[error(
"Broken Python installation, `platform.mac_ver()` returned an empty value, please reinstall Python"
)]
BrokenMacVer,
#[error("Unknown operating system: `{operating_system}`")]
UnknownOperatingSystem { operating_system: String },
@ -748,7 +750,9 @@ pub enum InterpreterInfoError {
UnsupportedPythonVersion { python_version: String },
#[error("Python executable does not support `-I` flag. Please use Python 3.8 or newer.")]
UnsupportedPython,
#[error("Python installation is missing `distutils`, which is required for packaging on older Python versions. Your system may package it separately, e.g., as `python{python_major}-distutils` or `python{python_major}.{python_minor}-distutils`.")]
#[error(
"Python installation is missing `distutils`, which is required for packaging on older Python versions. Your system may package it separately, e.g., as `python{python_major}-distutils` or `python{python_major}.{python_minor}-distutils`."
)]
MissingRequiredDistutils {
python_major: usize,
python_minor: usize,

View file

@ -636,12 +636,12 @@ mod tests {
})??;
assert!(
matches!(
python,
PythonInstallation {
source: PythonSource::SearchPath,
interpreter: _
}
),
python,
PythonInstallation {
source: PythonSource::SearchPath,
interpreter: _
}
),
"We should skip the Python 2 installation and find the Python 3 interpreter; got {python:?}"
);
assert_eq!(python.interpreter().sys_executable(), python3.path());
@ -937,12 +937,12 @@ mod tests {
})??;
assert!(
matches!(
python,
PythonInstallation {
source: PythonSource::SearchPathFirst,
interpreter: _
}
),
python,
PythonInstallation {
source: PythonSource::SearchPathFirst,
interpreter: _
}
),
"We should skip the active environment in favor of the requested version; got {python:?}"
);

View file

@ -16,7 +16,9 @@ use uv_fs::Simplified;
#[derive(Debug, Error)]
pub enum LibcDetectionError {
#[error("Could not detect either glibc version nor musl libc version, at least one of which is required")]
#[error(
"Could not detect either glibc version nor musl libc version, at least one of which is required"
)]
NoLibcFound,
#[error("Failed to get base name of symbolic link path {0}")]
MissingBasePath(PathBuf),
@ -66,7 +68,9 @@ pub(crate) fn detect_linux_libc() -> Result<LibcVersion, LibcDetectionError> {
match detect_linux_libc_from_ld_symlink(&ld_path) {
Ok(os) => return Ok(os),
Err(err) => {
trace!("Tried to find libc version from possible symlink at {ld_path:?}, but failed: {err}");
trace!(
"Tried to find libc version from possible symlink at {ld_path:?}, but failed: {err}"
);
}
}
match detect_glibc_version_from_ldd(&ld_path) {

View file

@ -215,7 +215,7 @@ impl ManagedPythonInstallations {
return Err(Error::ReadError {
dir: self.root.clone(),
err,
})
});
}
};
let scratch = self.scratch();
@ -487,7 +487,7 @@ impl ManagedPythonInstallation {
);
}
Err(err) if err.kind() == io::ErrorKind::NotFound => {
return Err(Error::MissingExecutable(python.clone()))
return Err(Error::MissingExecutable(python.clone()));
}
Err(err) if err.kind() == io::ErrorKind::AlreadyExists => {}
Err(err) => {
@ -495,7 +495,7 @@ impl ManagedPythonInstallation {
from: executable,
to: python,
err,
})
});
}
}
}

View file

@ -393,7 +393,10 @@ impl RequirementsTxt {
RequirementsTxtStatement::UnsupportedOption(flag) => {
if requirements_txt == Path::new("-") {
if flag.cli() {
uv_warnings::warn_user!("Ignoring unsupported option from stdin: `{flag}` (hint: pass `{flag}` on the command line instead)", flag = flag.green());
uv_warnings::warn_user!(
"Ignoring unsupported option from stdin: `{flag}` (hint: pass `{flag}` on the command line instead)",
flag = flag.green()
);
} else {
uv_warnings::warn_user!(
"Ignoring unsupported option from stdin: `{flag}`",
@ -402,7 +405,11 @@ impl RequirementsTxt {
}
} else {
if flag.cli() {
uv_warnings::warn_user!("Ignoring unsupported option in `{path}`: `{flag}` (hint: pass `{flag}` on the command line instead)", path = requirements_txt.user_display().cyan(), flag = flag.green());
uv_warnings::warn_user!(
"Ignoring unsupported option in `{path}`: `{flag}` (hint: pass `{flag}` on the command line instead)",
path = requirements_txt.user_display().cyan(),
flag = flag.green()
);
} else {
uv_warnings::warn_user!(
"Ignoring unsupported option in `{path}`: `{flag}`",
@ -1068,7 +1075,10 @@ impl Display for RequirementsTxtParserError {
write!(f, "Unsupported editable requirement")
}
Self::MissingRequirementPrefix(given) => {
write!(f, "Requirement `{given}` looks like a requirements file but was passed as a package name. Did you mean `-r {given}`?")
write!(
f,
"Requirement `{given}` looks like a requirements file but was passed as a package name. Did you mean `-r {given}`?"
)
}
Self::NoBinary { specifier, .. } => {
write!(f, "Invalid specifier for `--no-binary`: {specifier}")

View file

@ -76,13 +76,13 @@ impl RequirementsTxtRequirement {
let parsed_url = match url.parsed_url {
ParsedUrl::Directory(parsed_url) => parsed_url,
ParsedUrl::Path(_) => {
return Err(EditableError::File(requirement.name, url.to_string()))
return Err(EditableError::File(requirement.name, url.to_string()));
}
ParsedUrl::Archive(_) => {
return Err(EditableError::Https(requirement.name, url.to_string()))
return Err(EditableError::Https(requirement.name, url.to_string()));
}
ParsedUrl::Git(_) => {
return Err(EditableError::Git(requirement.name, url.to_string()))
return Err(EditableError::Git(requirement.name, url.to_string()));
}
};
@ -101,13 +101,13 @@ impl RequirementsTxtRequirement {
let parsed_url = match requirement.url.parsed_url {
ParsedUrl::Directory(parsed_url) => parsed_url,
ParsedUrl::Path(_) => {
return Err(EditableError::UnnamedFile(requirement.to_string()))
return Err(EditableError::UnnamedFile(requirement.to_string()));
}
ParsedUrl::Archive(_) => {
return Err(EditableError::UnnamedHttps(requirement.to_string()))
return Err(EditableError::UnnamedHttps(requirement.to_string()));
}
ParsedUrl::Git(_) => {
return Err(EditableError::UnnamedGit(requirement.to_string()))
return Err(EditableError::UnnamedGit(requirement.to_string()));
}
};

View file

@ -205,7 +205,7 @@ impl RequirementsSpecification {
return Err(anyhow::anyhow!(
"Conda environment files (i.e., `{}`) are not supported",
path.user_display()
))
));
}
})
}

View file

@ -262,7 +262,9 @@ impl CandidateSelector {
[] => {}
[dist] => {
if dist.version() == version {
debug!("Found installed version of {dist} that satisfies preference in {range}");
debug!(
"Found installed version of {dist} that satisfies preference in {range}"
);
return Some(Candidate {
name: package_name,
@ -278,7 +280,9 @@ impl CandidateSelector {
// We do not consider installed distributions with multiple versions because
// during installation these must be reinstalled from the remote
_ => {
debug!("Ignoring installed versions of {package_name}: multiple distributions found");
debug!(
"Ignoring installed versions of {package_name}: multiple distributions found"
);
}
}
}
@ -526,7 +530,9 @@ impl CandidateSelector {
let Some(dist) = maybe_dist.prioritized_dist() else {
continue;
};
trace!("Found candidate for package {package_name} with range {range} after {steps} steps: {version} version");
trace!(
"Found candidate for package {package_name} with range {range} after {steps} steps: {version} version"
);
Candidate::new(package_name, version, dist, VersionChoiceKind::Compatible)
};
@ -584,7 +590,9 @@ impl CandidateSelector {
return incompatible;
}
trace!("Exhausted all candidates for package {package_name} with range {range} after {steps} steps");
trace!(
"Exhausted all candidates for package {package_name} with range {range} after {steps} steps"
);
None
}
}

View file

@ -80,7 +80,9 @@ pub enum ResolveError {
#[error("Requirements contain conflicting indexes for package `{0}`: `{1}` vs. `{2}`")]
ConflictingIndexes(PackageName, String, String),
#[error("Package `{0}` attempted to resolve via URL: {1}. URL dependencies must be expressed as direct requirements or constraints. Consider adding `{0} @ {1}` to your dependencies or constraints file.")]
#[error(
"Package `{0}` attempted to resolve via URL: {1}. URL dependencies must be expressed as direct requirements or constraints. Consider adding `{0} @ {1}` to your dependencies or constraints file."
)]
DisallowedUrl(PackageName, String),
#[error(transparent)]
@ -103,7 +105,9 @@ pub enum ResolveError {
#[error("Attempted to construct an invalid version specifier")]
InvalidVersion(#[from] uv_pep440::VersionSpecifierBuildError),
#[error("In `--require-hashes` mode, all requirements must be pinned upfront with `==`, but found: `{0}`")]
#[error(
"In `--require-hashes` mode, all requirements must be pinned upfront with `==`, but found: `{0}`"
)]
UnhashedPackage(PackageName),
#[error("found conflicting distribution in resolution: {0}")]
@ -124,7 +128,9 @@ pub enum ResolveError {
#[source]
name_error: InvalidNameError,
},
#[error("The index returned metadata for the wrong package: expected {request} for {expected}, got {request} for {actual}")]
#[error(
"The index returned metadata for the wrong package: expected {request} for {expected}, got {request} for {actual}"
)]
MismatchedPackageName {
request: &'static str,
expected: PackageName,

View file

@ -217,7 +217,7 @@ impl FlatDistributions {
let priority = match tags {
Some(tags) => match filename.compatibility(tags) {
TagCompatibility::Incompatible(tag) => {
return WheelCompatibility::Incompatible(IncompatibleWheel::Tag(tag))
return WheelCompatibility::Incompatible(IncompatibleWheel::Tag(tag));
}
TagCompatibility::Compatible(priority) => Some(priority),
},

View file

@ -42,23 +42,41 @@ use crate::{Installable, LockError, RequiresPython, ResolverOutput};
#[derive(Debug, thiserror::Error)]
pub enum PylockTomlErrorKind {
#[error("Package `{0}` includes both a registry (`packages.wheels`) and a directory source (`packages.directory`)")]
#[error(
"Package `{0}` includes both a registry (`packages.wheels`) and a directory source (`packages.directory`)"
)]
WheelWithDirectory(PackageName),
#[error("Package `{0}` includes both a registry (`packages.wheels`) and a VCS source (`packages.vcs`)")]
#[error(
"Package `{0}` includes both a registry (`packages.wheels`) and a VCS source (`packages.vcs`)"
)]
WheelWithVcs(PackageName),
#[error("Package `{0}` includes both a registry (`packages.wheels`) and an archive source (`packages.archive`)")]
#[error(
"Package `{0}` includes both a registry (`packages.wheels`) and an archive source (`packages.archive`)"
)]
WheelWithArchive(PackageName),
#[error("Package `{0}` includes both a registry (`packages.sdist`) and a directory source (`packages.directory`)")]
#[error(
"Package `{0}` includes both a registry (`packages.sdist`) and a directory source (`packages.directory`)"
)]
SdistWithDirectory(PackageName),
#[error("Package `{0}` includes both a registry (`packages.sdist`) and a VCS source (`packages.vcs`)")]
#[error(
"Package `{0}` includes both a registry (`packages.sdist`) and a VCS source (`packages.vcs`)"
)]
SdistWithVcs(PackageName),
#[error("Package `{0}` includes both a registry (`packages.sdist`) and an archive source (`packages.archive`)")]
#[error(
"Package `{0}` includes both a registry (`packages.sdist`) and an archive source (`packages.archive`)"
)]
SdistWithArchive(PackageName),
#[error("Package `{0}` includes both a directory (`packages.directory`) and a VCS source (`packages.vcs`)")]
#[error(
"Package `{0}` includes both a directory (`packages.directory`) and a VCS source (`packages.vcs`)"
)]
DirectoryWithVcs(PackageName),
#[error("Package `{0}` includes both a directory (`packages.directory`) and an archive source (`packages.archive`)")]
#[error(
"Package `{0}` includes both a directory (`packages.directory`) and an archive source (`packages.archive`)"
)]
DirectoryWithArchive(PackageName),
#[error("Package `{0}` includes both a VCS (`packages.vcs`) and an archive source (`packages.archive`)")]
#[error(
"Package `{0}` includes both a VCS (`packages.vcs`) and an archive source (`packages.archive`)"
)]
VcsWithArchive(PackageName),
#[error(
"Package `{0}` must include one of: `wheels`, `directory`, `archive`, `sdist`, or `vcs`"
@ -82,17 +100,29 @@ pub enum PylockTomlErrorKind {
PathToUrl,
#[error("Failed to convert URL to path")]
UrlToPath,
#[error("Package `{0}` can't be installed because it doesn't have a source distribution or wheel for the current platform")]
#[error(
"Package `{0}` can't be installed because it doesn't have a source distribution or wheel for the current platform"
)]
NeitherSourceDistNorWheel(PackageName),
#[error("Package `{0}` can't be installed because it is marked as both `--no-binary` and `--no-build`")]
#[error(
"Package `{0}` can't be installed because it is marked as both `--no-binary` and `--no-build`"
)]
NoBinaryNoBuild(PackageName),
#[error("Package `{0}` can't be installed because it is marked as `--no-binary` but has no source distribution")]
#[error(
"Package `{0}` can't be installed because it is marked as `--no-binary` but has no source distribution"
)]
NoBinary(PackageName),
#[error("Package `{0}` can't be installed because it is marked as `--no-build` but has no binary distribution")]
#[error(
"Package `{0}` can't be installed because it is marked as `--no-build` but has no binary distribution"
)]
NoBuild(PackageName),
#[error("Package `{0}` can't be installed because the binary distribution is incompatible with the current platform")]
#[error(
"Package `{0}` can't be installed because the binary distribution is incompatible with the current platform"
)]
IncompatibleWheelOnly(PackageName),
#[error("Package `{0}` can't be installed because it is marked as `--no-binary` but is itself a binary distribution")]
#[error(
"Package `{0}` can't be installed because it is marked as `--no-binary` but is itself a binary distribution"
)]
NoBinaryWheelOnly(PackageName),
#[error(transparent)]
WheelFilename(#[from] WheelFilenameError),

View file

@ -4111,7 +4111,7 @@ impl Wheel {
name: filename.name,
version: filename.version,
}
.into())
.into());
}
};
let file = Box::new(uv_distribution_types::File {
@ -4141,7 +4141,7 @@ impl Wheel {
name: filename.name,
version: filename.version,
}
.into())
.into());
}
};
let file_url = Url::from_file_path(root.join(index_path).join(file_path))

View file

@ -1408,7 +1408,8 @@ impl std::fmt::Display for PubGrubHint {
"hint".bold().cyan(),
":".bold(),
requires_python.cyan(),
PackageRange::compatibility(&PubGrubPackage::base(name), package_set, None).cyan(),
PackageRange::compatibility(&PubGrubPackage::base(name), package_set, None)
.cyan(),
package_requires_python.cyan(),
package_requires_python.cyan(),
)
@ -1426,7 +1427,8 @@ impl std::fmt::Display for PubGrubHint {
"hint".bold().cyan(),
":".bold(),
requires_python.cyan(),
PackageRange::compatibility(&PubGrubPackage::base(name), package_set, None).cyan(),
PackageRange::compatibility(&PubGrubPackage::base(name), package_set, None)
.cyan(),
package_requires_python.cyan(),
)
}
@ -1442,7 +1444,8 @@ impl std::fmt::Display for PubGrubHint {
"{}{} The Python interpreter uses a Python version that is not supported by your dependencies (e.g., {} only supports {}). Consider passing a `--python-version` value to raise the minimum supported version.",
"hint".bold().cyan(),
":".bold(),
PackageRange::compatibility(&PubGrubPackage::base(name), package_set, None).cyan(),
PackageRange::compatibility(&PubGrubPackage::base(name), package_set, None)
.cyan(),
package_requires_python.cyan(),
)
}

View file

@ -1857,7 +1857,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
url: None,
})
.collect(),
))
));
}
// Add a dependency on both the extra and base package, with and without the marker.
@ -1885,7 +1885,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
})
})
.collect(),
))
));
}
// Add a dependency on the dependency group, with and without the marker.
@ -1905,7 +1905,7 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
url: None,
})
.collect(),
))
));
}
};
Ok(Dependencies::Available(dependencies))
@ -2422,7 +2422,9 @@ impl<InstalledPackages: InstalledPackagesProvider> ResolverState<InstalledPackag
if !self.selector.use_highest_version(&package_name, &env) {
if let Some((lower, _)) = range.iter().next() {
if lower == &Bound::Unbounded {
debug!("Skipping prefetch for unbounded minimum-version range: {package_name} ({range})");
debug!(
"Skipping prefetch for unbounded minimum-version range: {package_name} ({range})"
);
return Ok(None);
}
}

View file

@ -917,7 +917,9 @@ mod tests {
let cm = resolve_conflicts(cm, &known_conflicts);
assert_eq!(
cm.try_to_string().as_deref(),
Some("(python_full_version < '3.10' and sys_platform != 'darwin') or (python_full_version >= '3.10' and sys_platform == 'darwin')")
Some(
"(python_full_version < '3.10' and sys_platform != 'darwin') or (python_full_version >= '3.10' and sys_platform == 'darwin')"
)
);
let cm = MarkerTree::from_str("python_version >= '3.10' and extra == 'extra-3-pkg-foo'")

View file

@ -49,11 +49,13 @@ impl Accelerator {
Ok(content) => {
return match parse_sys_module_nvidia_version(&content) {
Ok(driver_version) => {
debug!("Detected CUDA driver version from `/sys/module/nvidia/version`: {driver_version}");
debug!(
"Detected CUDA driver version from `/sys/module/nvidia/version`: {driver_version}"
);
Ok(Some(Self::Cuda { driver_version }))
}
Err(e) => Err(e),
}
};
}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => return Err(e.into()),
@ -61,18 +63,20 @@ impl Accelerator {
// Read from `/proc/driver/nvidia/version`
match fs_err::read_to_string("/proc/driver/nvidia/version") {
Ok(content) => {
match parse_proc_driver_nvidia_version(&content) {
Ok(Some(driver_version)) => {
debug!("Detected CUDA driver version from `/proc/driver/nvidia/version`: {driver_version}");
return Ok(Some(Self::Cuda { driver_version }));
}
Ok(None) => {
debug!("Failed to parse CUDA driver version from `/proc/driver/nvidia/version`");
}
Err(e) => return Err(e),
Ok(content) => match parse_proc_driver_nvidia_version(&content) {
Ok(Some(driver_version)) => {
debug!(
"Detected CUDA driver version from `/proc/driver/nvidia/version`: {driver_version}"
);
return Ok(Some(Self::Cuda { driver_version }));
}
}
Ok(None) => {
debug!(
"Failed to parse CUDA driver version from `/proc/driver/nvidia/version`"
);
}
Err(e) => return Err(e),
},
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => return Err(e.into()),
}

View file

@ -333,6 +333,8 @@ pub enum HashStrategyError {
UnpinnedRequirement(String, HashCheckingMode),
#[error("In `{1}` mode, all requirements must have a hash, but none were provided for: {0}")]
MissingHashes(String, HashCheckingMode),
#[error("In `{1}` mode, all requirements must have a hash, but there were no overlapping hashes between the requirements and constraints for: {0}")]
#[error(
"In `{1}` mode, all requirements must have a hash, but there were no overlapping hashes between the requirements and constraints for: {0}"
)]
NoIntersection(String, HashCheckingMode),
}

View file

@ -11,7 +11,9 @@ mod virtualenv;
pub enum Error {
#[error(transparent)]
Io(#[from] io::Error),
#[error("Could not find a suitable Python executable for the virtual environment based on the interpreter: {0}")]
#[error(
"Could not find a suitable Python executable for the virtual environment based on the interpreter: {0}"
)]
NotFound(String),
}

View file

@ -151,7 +151,9 @@ pub enum DependencyGroupError {
),
#[error("Failed to find group `{0}` included by `{1}`")]
GroupNotFound(GroupName, GroupName),
#[error("Group `{0}` includes the `dev` group (`include = \"dev\"`), but only `tool.uv.dev-dependencies` was found. To reference the `dev` group via an `include`, remove the `tool.uv.dev-dependencies` section and add any development dependencies to the `dev` entry in the `[dependency-groups]` table instead.")]
#[error(
"Group `{0}` includes the `dev` group (`include = \"dev\"`), but only `tool.uv.dev-dependencies` was found. To reference the `dev` group via an `include`, remove the `tool.uv.dev-dependencies` section and add any development dependencies to the `dev` entry in the `[dependency-groups]` table instead."
)]
DevGroupInclude(GroupName),
#[error("Detected a cycle in `dependency-groups`: {0}")]
DependencyGroupCycle(Cycle),

View file

@ -1487,6 +1487,14 @@ mod test {
("flask[dotenv]", ">=1.0")
);
assert_eq!(split_specifiers("flask[dotenv]"), ("flask[dotenv]", ""));
assert_eq!(split_specifiers("flask @ https://files.pythonhosted.org/packages/af/47/93213ee66ef8fae3b93b3e29206f6b251e65c97bd91d8e1c5596ef15af0a/flask-3.1.0-py3-none-any.whl"), ("flask", "@ https://files.pythonhosted.org/packages/af/47/93213ee66ef8fae3b93b3e29206f6b251e65c97bd91d8e1c5596ef15af0a/flask-3.1.0-py3-none-any.whl"));
assert_eq!(
split_specifiers(
"flask @ https://files.pythonhosted.org/packages/af/47/93213ee66ef8fae3b93b3e29206f6b251e65c97bd91d8e1c5596ef15af0a/flask-3.1.0-py3-none-any.whl"
),
(
"flask",
"@ https://files.pythonhosted.org/packages/af/47/93213ee66ef8fae3b93b3e29206f6b251e65c97bd91d8e1c5596ef15af0a/flask-3.1.0-py3-none-any.whl"
)
);
}
}

View file

@ -272,7 +272,13 @@ async fn build_impl(
if !package.pyproject_toml().is_package() {
let name = &package.project().name;
let pyproject_toml = package.root().join("pyproject.toml");
return Err(anyhow::anyhow!("Package `{}` is missing a `{}`. For example, to build with `{}`, add the following to `{}`:\n```toml\n[build-system]\nrequires = [\"setuptools\"]\nbuild-backend = \"setuptools.build_meta\"\n```", name.cyan(), "build-system".green(), "setuptools".cyan(), pyproject_toml.user_display().cyan()));
return Err(anyhow::anyhow!(
"Package `{}` is missing a `{}`. For example, to build with `{}`, add the following to `{}`:\n```toml\n[build-system]\nrequires = [\"setuptools\"]\nbuild-backend = \"setuptools.build_meta\"\n```",
name.cyan(),
"build-system".green(),
"setuptools".cyan(),
pyproject_toml.user_display().cyan()
));
}
vec![AnnotatedSource::from(Source::Directory(Cow::Borrowed(
@ -311,7 +317,13 @@ async fn build_impl(
let member = workspace.packages().values().next().unwrap();
let name = &member.project().name;
let pyproject_toml = member.root().join("pyproject.toml");
return Err(anyhow::anyhow!("Workspace does not contain any buildable packages. For example, to build `{}` with `{}`, add a `{}` to `{}`:\n```toml\n[build-system]\nrequires = [\"setuptools\"]\nbuild-backend = \"setuptools.build_meta\"\n```", name.cyan(), "setuptools".cyan(), "build-system".green(), pyproject_toml.user_display().cyan()));
return Err(anyhow::anyhow!(
"Workspace does not contain any buildable packages. For example, to build `{}` with `{}`, add a `{}` to `{}`:\n```toml\n[build-system]\nrequires = [\"setuptools\"]\nbuild-backend = \"setuptools.build_meta\"\n```",
name.cyan(),
"setuptools".cyan(),
"build-system".green(),
pyproject_toml.user_display().cyan()
));
}
packages

View file

@ -533,7 +533,7 @@ pub(crate) async fn pip_compile(
Err(err) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
};
@ -655,7 +655,9 @@ pub(crate) async fn pip_compile(
}
ExportFormat::PylockToml => {
if include_marker_expression {
warn_user!("The `--emit-marker-expression` option is not supported for `pylock.toml` output");
warn_user!(
"The `--emit-marker-expression` option is not supported for `pylock.toml` output"
);
}
if include_index_url {
warn_user!(
@ -673,7 +675,9 @@ pub(crate) async fn pip_compile(
);
}
if include_index_annotation {
warn_user!("The `--emit-index-annotation` option is not supported for `pylock.toml` output");
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.

View file

@ -133,7 +133,9 @@ pub(crate) async fn pip_install(
if pylock.is_some() {
if preview.is_disabled() {
warn_user!("The `--pylock` setting is experimental and may change without warning. Pass `--preview` to disable this warning.");
warn_user!(
"The `--pylock` setting is experimental and may change without warning. Pass `--preview` to disable this warning."
);
}
}
@ -494,7 +496,7 @@ pub(crate) async fn pip_install(
Err(err) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
};
@ -531,7 +533,7 @@ pub(crate) async fn pip_install(
Err(err) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
}

View file

@ -50,7 +50,7 @@ impl LatestClient<'_> {
uv_client::ErrorKind::NoIndex(_) => Ok(None),
uv_client::ErrorKind::Offline(_) => Ok(None),
kind => Err(kind.into()),
}
};
}
};

View file

@ -124,7 +124,9 @@ pub(crate) async fn pip_sync(
if pylock.is_some() {
if preview.is_disabled() {
warn_user!("The `--pylock` setting is experimental and may change without warning. Pass `--preview` to disable this warning.");
warn_user!(
"The `--pylock` setting is experimental and may change without warning. Pass `--preview` to disable this warning."
);
}
}
@ -137,7 +139,10 @@ pub(crate) async fn pip_sync(
let num_requirements =
requirements.len() + source_trees.len() + usize::from(pylock.is_some());
if num_requirements == 0 {
writeln!(printer.stderr(), "No requirements found (hint: use `--allow-empty-requirements` to clear the environment)")?;
writeln!(
printer.stderr(),
"No requirements found (hint: use `--allow-empty-requirements` to clear the environment)"
)?;
return Ok(ExitStatus::Success);
}
}
@ -427,7 +432,7 @@ pub(crate) async fn pip_sync(
Err(err) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
};
@ -464,7 +469,7 @@ pub(crate) async fn pip_sync(
Err(err) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
}

View file

@ -212,10 +212,16 @@ pub(crate) async fn add(
if project.is_non_project() {
match dependency_type {
DependencyType::Production => {
bail!("Project is missing a `[project]` table; add a `[project]` table to use production dependencies, or run `{}` instead", "uv add --dev".green())
bail!(
"Project is missing a `[project]` table; add a `[project]` table to use production dependencies, or run `{}` instead",
"uv add --dev".green()
)
}
DependencyType::Optional(_) => {
bail!("Project is missing a `[project]` table; add a `[project]` table to use optional dependencies, or run `{}` instead", "uv add --dev".green())
bail!(
"Project is missing a `[project]` table; add a `[project]` table to use optional dependencies, or run `{}` instead",
"uv add --dev".green()
)
}
DependencyType::Group(_) => {}
DependencyType::Dev => (),

View file

@ -200,7 +200,7 @@ pub(crate) async fn export(
Err(ProjectError::Operation(err)) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
};

View file

@ -531,9 +531,13 @@ async fn do_lock(
if requires_python.is_unbounded() {
let default =
RequiresPython::greater_than_equal_version(&interpreter.python_minor_version());
warn_user_once!("The workspace `requires-python` value (`{requires_python}`) does not contain a lower bound. Add a lower bound to indicate the minimum compatible Python version (e.g., `{default}`).");
warn_user_once!(
"The workspace `requires-python` value (`{requires_python}`) does not contain a lower bound. Add a lower bound to indicate the minimum compatible Python version (e.g., `{default}`)."
);
} else if requires_python.is_exact_without_patch() {
warn_user_once!("The workspace `requires-python` value (`{requires_python}`) contains an exact match without a patch version. When omitted, the patch version is implicitly `0` (e.g., `{requires_python}.0`). Did you mean `{requires_python}.*`?");
warn_user_once!(
"The workspace `requires-python` value (`{requires_python}`) contains an exact match without a patch version. When omitted, the patch version is implicitly `0` (e.g., `{requires_python}.0`). Did you mean `{requires_python}.*`?"
);
}
requires_python
} else {
@ -1016,8 +1020,12 @@ impl ValidatedLock {
if let Err((fork_markers_union, environments_union)) = lock.check_marker_coverage() {
warn_user!(
"Ignoring existing lockfile due to fork markers not covering the supported environments: `{}` vs `{}`",
fork_markers_union.try_to_string().unwrap_or("true".to_string()),
environments_union.try_to_string().unwrap_or("true".to_string()),
fork_markers_union
.try_to_string()
.unwrap_or("true".to_string()),
environments_union
.try_to_string()
.unwrap_or("true".to_string()),
);
return Ok(Self::Versions(lock));
}
@ -1183,7 +1191,8 @@ impl ValidatedLock {
}
SatisfiesResult::MissingLocalIndex(name, version, index) => {
debug!(
"Ignoring existing lockfile due to missing local index: `{name}` `{version}` from `{}`", index.display()
"Ignoring existing lockfile due to missing local index: `{name}` `{version}` from `{}`",
index.display()
);
Ok(Self::Preferable(lock))
}

View file

@ -70,7 +70,9 @@ pub(crate) mod tree;
#[derive(thiserror::Error, Debug)]
pub(crate) enum ProjectError {
#[error("The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`.")]
#[error(
"The lockfile at `uv.lock` needs to be updated, but `--locked` was provided. To update the lockfile, run `uv lock`."
)]
LockMismatch(Box<Lock>),
#[error(
@ -78,40 +80,60 @@ pub(crate) enum ProjectError {
)]
MissingLockfile,
#[error("The lockfile at `uv.lock` uses an unsupported schema version (v{1}, but only v{0} is supported). Downgrade to a compatible uv version, or remove the `uv.lock` prior to running `uv lock` or `uv sync`.")]
#[error(
"The lockfile at `uv.lock` uses an unsupported schema version (v{1}, but only v{0} is supported). Downgrade to a compatible uv version, or remove the `uv.lock` prior to running `uv lock` or `uv sync`."
)]
UnsupportedLockVersion(u32, u32),
#[error("Failed to parse `uv.lock`, which uses an unsupported schema version (v{1}, but only v{0} is supported). Downgrade to a compatible uv version, or remove the `uv.lock` prior to running `uv lock` or `uv sync`.")]
#[error(
"Failed to parse `uv.lock`, which uses an unsupported schema version (v{1}, but only v{0} is supported). Downgrade to a compatible uv version, or remove the `uv.lock` prior to running `uv lock` or `uv sync`."
)]
UnparsableLockVersion(u32, u32, #[source] toml::de::Error),
#[error("Failed to serialize `uv.lock`")]
LockSerialization(#[from] toml_edit::ser::Error),
#[error("The current Python version ({0}) is not compatible with the locked Python requirement: `{1}`")]
#[error(
"The current Python version ({0}) is not compatible with the locked Python requirement: `{1}`"
)]
LockedPythonIncompatibility(Version, RequiresPython),
#[error("The current Python platform is not compatible with the lockfile's supported environments: {0}")]
#[error(
"The current Python platform is not compatible with the lockfile's supported environments: {0}"
)]
LockedPlatformIncompatibility(String),
#[error(transparent)]
Conflict(#[from] ConflictError),
#[error("The requested interpreter resolved to Python {0}, which is incompatible with the project's Python requirement: `{1}`")]
#[error(
"The requested interpreter resolved to Python {0}, which is incompatible with the project's Python requirement: `{1}`"
)]
RequestedPythonProjectIncompatibility(Version, RequiresPython),
#[error("The Python request from `{0}` resolved to Python {1}, which is incompatible with the project's Python requirement: `{2}`. Use `uv python pin` to update the `.python-version` file to a compatible version.")]
#[error(
"The Python request from `{0}` resolved to Python {1}, which is incompatible with the project's Python requirement: `{2}`. Use `uv python pin` to update the `.python-version` file to a compatible version."
)]
DotPythonVersionProjectIncompatibility(String, Version, RequiresPython),
#[error("The resolved Python interpreter (Python {0}) is incompatible with the project's Python requirement: `{1}`")]
#[error(
"The resolved Python interpreter (Python {0}) is incompatible with the project's Python requirement: `{1}`"
)]
RequiresPythonProjectIncompatibility(Version, RequiresPython),
#[error("The requested interpreter resolved to Python {0}, which is incompatible with the script's Python requirement: `{1}`")]
#[error(
"The requested interpreter resolved to Python {0}, which is incompatible with the script's Python requirement: `{1}`"
)]
RequestedPythonScriptIncompatibility(Version, RequiresPython),
#[error("The Python request from `{0}` resolved to Python {1}, which is incompatible with the script's Python requirement: `{2}`")]
#[error(
"The Python request from `{0}` resolved to Python {1}, which is incompatible with the script's Python requirement: `{2}`"
)]
DotPythonVersionScriptIncompatibility(String, Version, RequiresPython),
#[error("The resolved Python interpreter (Python {0}) is incompatible with the script's Python requirement: `{1}`")]
#[error(
"The resolved Python interpreter (Python {0}) is incompatible with the script's Python requirement: `{1}`"
)]
RequiresPythonScriptIncompatibility(Version, RequiresPython),
#[error("The requested interpreter resolved to Python {0}, which is incompatible with the project's Python requirement: `{1}`. However, a workspace member (`{member}`) supports Python {3}. To install the workspace member on its own, navigate to `{path}`, then run `{venv}` followed by `{install}`.", member = _2.cyan(), venv = format!("uv venv --python {_0}").green(), install = "uv pip install -e .".green(), path = _4.user_display().cyan() )]
@ -151,7 +173,9 @@ pub(crate) enum ProjectError {
#[error("PEP 723 scripts do not support dependency groups, but group `{0}` was specified")]
MissingGroupScript(GroupName),
#[error("Default group `{0}` (from `tool.uv.default-groups`) is not defined in the project's `dependency-groups` table")]
#[error(
"Default group `{0}` (from `tool.uv.default-groups`) is not defined in the project's `dependency-groups` table"
)]
MissingDefaultGroup(GroupName),
#[error("Extra `{0}` is not defined in the project's `optional-dependencies` table")]
@ -785,7 +809,9 @@ pub(crate) enum EnvironmentIncompatibilityError {
#[error("The {0} environment's Python version does not meet the Python requirement: `{1}`")]
RequiresPython(EnvironmentKind, RequiresPython),
#[error("The interpreter in the {0} environment has different version ({1}) than it was created with ({2})")]
#[error(
"The interpreter in the {0} environment has different version ({1}) than it was created with ({2})"
)]
PyenvVersionConflict(EnvironmentKind, Version, Version),
}
@ -899,7 +925,7 @@ impl ProjectInterpreter {
return Err(ProjectError::InvalidProjectEnvironmentDir(
root,
inner.kind.to_string(),
))
));
}
InvalidEnvironmentKind::MissingExecutable(_) => {
if fs_err::read_dir(&root).is_ok_and(|mut dir| dir.next().is_some()) {
@ -1264,7 +1290,9 @@ impl ProjectEnvironment {
(_, Err(err)) | (Err(err), _) => {
return Err(ProjectError::InvalidProjectEnvironmentDir(
root,
format!("it is not a compatible environment but cannot be recreated because uv cannot determine if it is a virtual environment: {err}"),
format!(
"it is not a compatible environment but cannot be recreated because uv cannot determine if it is a virtual environment: {err}"
),
));
}
};
@ -2561,7 +2589,9 @@ fn warn_on_requirements_txt_setting(spec: &RequirementsSpecification, settings:
if settings.index_locations.no_index() {
// Nothing to do, we're ignoring the URLs anyway.
} else if *no_index {
warn_user_once!("Ignoring `--no-index` from requirements file. Instead, use the `--no-index` command-line argument, or set `no-index` in a `uv.toml` or `pyproject.toml` file.");
warn_user_once!(
"Ignoring `--no-index` from requirements file. Instead, use the `--no-index` command-line argument, or set `no-index` in a `uv.toml` or `pyproject.toml` file."
);
} else {
if let Some(index_url) = index_url {
if settings.index_locations.default_index().map(Index::url) != Some(index_url) {
@ -2578,7 +2608,6 @@ fn warn_on_requirements_txt_setting(spec: &RequirementsSpecification, settings:
{
warn_user_once!(
"Ignoring `--extra-index-url` from requirements file: `{extra_index_url}`. Instead, use the `--extra-index-url` command-line argument, or set `extra-index-url` in a `uv.toml` or `pyproject.toml` file.`"
);
}
}
@ -2596,11 +2625,15 @@ fn warn_on_requirements_txt_setting(spec: &RequirementsSpecification, settings:
}
if !no_binary.is_none() && settings.build_options.no_binary() != no_binary {
warn_user_once!("Ignoring `--no-binary` setting from requirements file. Instead, use the `--no-binary` command-line argument, or set `no-binary` in a `uv.toml` or `pyproject.toml` file.");
warn_user_once!(
"Ignoring `--no-binary` setting from requirements file. Instead, use the `--no-binary` command-line argument, or set `no-binary` in a `uv.toml` or `pyproject.toml` file."
);
}
if !no_build.is_none() && settings.build_options.no_build() != no_build {
warn_user_once!("Ignoring `--no-binary` setting from requirements file. Instead, use the `--no-build` command-line argument, or set `no-build` in a `uv.toml` or `pyproject.toml` file.");
warn_user_once!(
"Ignoring `--no-binary` setting from requirements file. Instead, use the `--no-build` command-line argument, or set `no-build` in a `uv.toml` or `pyproject.toml` file."
);
}
}

View file

@ -297,7 +297,7 @@ pub(crate) async fn remove(
Err(ProjectError::Operation(err)) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
};
@ -363,7 +363,7 @@ pub(crate) async fn remove(
Err(ProjectError::Operation(err)) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
}

View file

@ -273,7 +273,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
)
.with_context("script")
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
};
@ -318,7 +318,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
)
.with_context("script")
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
}
@ -414,7 +414,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
)
.with_context("script")
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
}
@ -717,7 +717,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
network_settings.native_tls,
)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
};
@ -806,7 +806,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
network_settings.native_tls,
)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
}
@ -968,7 +968,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
)
.with_context("`--with`")
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
};
@ -1562,7 +1562,7 @@ fn read_recursion_depth_from_environment_variable() -> anyhow::Result<u32> {
Err(VarError::NotPresent) => return Ok(0),
Err(e) => {
return Err(e)
.with_context(|| format!("invalid value for {}", EnvVars::UV_RUN_RECURSION_DEPTH))
.with_context(|| format!("invalid value for {}", EnvVars::UV_RUN_RECURSION_DEPTH));
}
};

View file

@ -108,7 +108,9 @@ pub(crate) async fn sync(
if project.workspace().pyproject_toml().has_scripts()
&& !project.workspace().pyproject_toml().is_package()
{
warn_user!("Skipping installation of entry points (`project.scripts`) because this project is not packaged; to install entry points, set `tool.uv.package = true` or define a `build-system`");
warn_user!(
"Skipping installation of entry points (`project.scripts`) because this project is not packaged; to install entry points, set `tool.uv.package = true` or define a `build-system`"
);
}
SyncTarget::Project(project)
@ -330,7 +332,7 @@ pub(crate) async fn sync(
network_settings.native_tls,
)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
}
@ -413,7 +415,7 @@ pub(crate) async fn sync(
Err(ProjectError::Operation(err)) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(ProjectError::LockMismatch(lock)) if dry_run.enabled() => {
// The lockfile is mismatched, but we're in dry-run mode. We should proceed with the
@ -455,7 +457,7 @@ pub(crate) async fn sync(
Err(ProjectError::Operation(err)) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
}

View file

@ -152,7 +152,7 @@ pub(crate) async fn tree(
Err(ProjectError::Operation(err)) => {
return diagnostics::OperationDiagnostic::native_tls(native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
};

View file

@ -144,7 +144,10 @@ pub(crate) async fn install(
let start = std::time::Instant::now();
if default && !preview.is_enabled() {
writeln!(printer.stderr(), "The `--default` flag is only available in preview mode; add the `--preview` flag to use `--default`")?;
writeln!(
printer.stderr(),
"The `--default` flag is only available in preview mode; add the `--preview` flag to use `--default`"
)?;
return Ok(ExitStatus::Failure);
}

View file

@ -124,7 +124,11 @@ pub(crate) async fn install(
// If the user provided an executable name, verify that it matches the `--from` requirement.
let executable = if let Some(executable) = request.executable {
let Ok(executable) = PackageName::from_str(executable) else {
bail!("Package requirement (`{from}`) provided with `--from` conflicts with install request (`{executable}`)", from = from.cyan(), executable = executable.cyan())
bail!(
"Package requirement (`{from}`) provided with `--from` conflicts with install request (`{executable}`)",
from = from.cyan(),
executable = executable.cyan()
)
};
Some(executable)
} else {
@ -441,7 +445,7 @@ pub(crate) async fn install(
Err(ProjectError::Operation(err)) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
};
@ -573,7 +577,7 @@ pub(crate) async fn install(
Err(ProjectError::Operation(err)) => {
return diagnostics::OperationDiagnostic::native_tls(network_settings.native_tls)
.report(err)
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()))
.map_or(Ok(ExitStatus::Failure), |err| Err(err.into()));
}
Err(err) => return Err(err.into()),
}

View file

@ -162,7 +162,9 @@ pub(crate) async fn run(
};
let Some(target) = target.to_str() else {
return Err(anyhow::anyhow!("Tool command could not be parsed as UTF-8 string. Use `--from` to specify the package name"));
return Err(anyhow::anyhow!(
"Tool command could not be parsed as UTF-8 string. Use `--from` to specify the package name"
));
};
if let Some(ref from) = from {
@ -173,7 +175,13 @@ pub(crate) async fn run(
"hint".bold().cyan(),
":".bold(),
package_name.cyan(),
format!("{} --from {} {}", invocation_source, package_name.cyan(), target).green(),
format!(
"{} --from {} {}",
invocation_source,
package_name.cyan(),
target
)
.green(),
));
}
} else {
@ -231,7 +239,9 @@ pub(crate) async fn run(
return Err(anyhow::anyhow!("No tool command provided"));
};
let Some(next_target) = next_target.to_str() else {
return Err(anyhow::anyhow!("Tool command could not be parsed as UTF-8 string. Use `--from` to specify the package name"));
return Err(anyhow::anyhow!(
"Tool command could not be parsed as UTF-8 string. Use `--from` to specify the package name"
));
};
target = next_target;
args = next_args;
@ -581,13 +591,14 @@ impl std::fmt::Display for ExecutableProviderHints<'_> {
package.name(),
executable
);
write!(f,
"An executable named `{}` is not provided by package `{}` but is available via the dependency `{}`. Consider using `{}` instead.",
executable.cyan(),
from.name.cyan(),
package.name().cyan(),
suggested_command.green()
)?;
write!(
f,
"An executable named `{}` is not provided by package `{}` but is available via the dependency `{}`. Consider using `{}` instead.",
executable.cyan(),
from.name.cyan(),
package.name().cyan(),
suggested_command.green()
)?;
}
packages => {
let provided_by = packages
@ -597,15 +608,17 @@ impl std::fmt::Display for ExecutableProviderHints<'_> {
.join("\n");
if self.not_from_expected() {
let suggested_command = format!("{invocation_source} --from PKG {executable}");
write!(f,
"An executable named `{}` is not provided by package `{}` but is available via the following dependencies:\n- {}\nConsider using `{}` instead.",
executable.cyan(),
from.name.cyan(),
provided_by,
suggested_command.green(),
)?;
write!(
f,
"An executable named `{}` is not provided by package `{}` but is available via the following dependencies:\n- {}\nConsider using `{}` instead.",
executable.cyan(),
from.name.cyan(),
provided_by,
suggested_command.green(),
)?;
} else {
write!(f,
write!(
f,
"An executable named `{}` is provided by package `{}` but is also available via the following dependencies:\n- {}\nUnexpected behavior may occur.",
executable.cyan(),
from.name.cyan(),
@ -694,7 +707,7 @@ async fn get_or_create_environment(
return Err(anyhow::anyhow!(
"Requesting the 'latest' Python version is not yet supported"
)
.into())
.into());
}
};

View file

@ -53,18 +53,27 @@ pub(crate) async fn update_shell(printer: Printer) -> Result<ExitStatus> {
// Determine the current shell.
let Some(shell) = Shell::from_env() else {
return Err(anyhow::anyhow!("The executable directory {} is not in PATH, but the current shell could not be determined", executable_directory.simplified_display().cyan()));
return Err(anyhow::anyhow!(
"The executable directory {} is not in PATH, but the current shell could not be determined",
executable_directory.simplified_display().cyan()
));
};
// Look up the configuration files (e.g., `.bashrc`, `.zshrc`) for the shell.
let files = shell.configuration_files();
if files.is_empty() {
return Err(anyhow::anyhow!("The executable directory {} is not in PATH, but updating {shell} is currently unsupported", executable_directory.simplified_display().cyan()));
return Err(anyhow::anyhow!(
"The executable directory {} is not in PATH, but updating {shell} is currently unsupported",
executable_directory.simplified_display().cyan()
));
}
// Prepare the command (e.g., `export PATH="$HOME/.cargo/bin:$PATH"`).
let Some(command) = shell.prepend_path(&executable_directory) else {
return Err(anyhow::anyhow!("The executable directory {} is not in PATH, but the necessary command to update {shell} could not be determined", executable_directory.simplified_display().cyan()));
return Err(anyhow::anyhow!(
"The executable directory {} is not in PATH, but the necessary command to update {shell} could not be determined",
executable_directory.simplified_display().cyan()
));
};
// Update each file, as necessary.
@ -136,6 +145,9 @@ pub(crate) async fn update_shell(printer: Printer) -> Result<ExitStatus> {
writeln!(printer.stderr(), "Restart your shell to apply changes")?;
Ok(ExitStatus::Success)
} else {
Err(anyhow::anyhow!("The executable directory {} is not in PATH, but the {shell} configuration files are already up-to-date", executable_directory.simplified_display().cyan()))
Err(anyhow::anyhow!(
"The executable directory {} is not in PATH, but the {shell} configuration files are already up-to-date",
executable_directory.simplified_display().cyan()
))
}
}

View file

@ -57,7 +57,10 @@ pub(crate) async fn project_version(
return Err(err)?;
}
// Otherwise, warn and provide fallback
warn_user!("Failed to read project metadata ({err}). Running `{}` for compatibility. This fallback will be removed in the future; pass `--preview` to force an error.", "uv self version".green());
warn_user!(
"Failed to read project metadata ({err}). Running `{}` for compatibility. This fallback will be removed in the future; pass `--preview` to force an error.",
"uv self version".green()
);
return self_version(short, output_format, printer);
}
};

View file

@ -93,19 +93,25 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
// `--isolated` moved to `--no-workspace`.
Commands::Project(command) if matches!(**command, ProjectCommand::Init(_)) => {
warn_user!("The `--isolated` flag is deprecated and has no effect. Instead, use `--no-config` to prevent uv from discovering configuration files or `--no-workspace` to prevent uv from adding the initialized project to the containing workspace.");
warn_user!(
"The `--isolated` flag is deprecated and has no effect. Instead, use `--no-config` to prevent uv from discovering configuration files or `--no-workspace` to prevent uv from adding the initialized project to the containing workspace."
);
false
}
// Preview APIs. Ignore `--isolated` and warn.
Commands::Project(_) | Commands::Tool(_) | Commands::Python(_) => {
warn_user!("The `--isolated` flag is deprecated and has no effect. Instead, use `--no-config` to prevent uv from discovering configuration files.");
warn_user!(
"The `--isolated` flag is deprecated and has no effect. Instead, use `--no-config` to prevent uv from discovering configuration files."
);
false
}
// Non-preview APIs. Continue to support `--isolated`, but warn.
_ => {
warn_user!("The `--isolated` flag is deprecated. Instead, use `--no-config` to prevent uv from discovering configuration files.");
warn_user!(
"The `--isolated` flag is deprecated. Instead, use `--no-config` to prevent uv from discovering configuration files."
);
true
}
}
@ -125,7 +131,9 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
.file_name()
.is_some_and(|file_name| file_name == "pyproject.toml")
{
warn_user!("The `--config-file` argument expects to receive a `uv.toml` file, not a `pyproject.toml`. If you're trying to run a command from another project, use the `--project` argument instead.");
warn_user!(
"The `--config-file` argument expects to receive a `uv.toml` file, not a `pyproject.toml`. If you're trying to run a command from another project, use the `--project` argument instead."
);
}
Some(FilesystemOptions::from_file(config_file)?)
} else if deprecated_isolated || cli.top_level.no_config {
@ -977,11 +985,15 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
args.compat_args.validate()?;
if args.no_system {
warn_user_once!("The `--no-system` flag has no effect, a system Python interpreter is always used in `uv venv`");
warn_user_once!(
"The `--no-system` flag has no effect, a system Python interpreter is always used in `uv venv`"
);
}
if args.system {
warn_user_once!("The `--system` flag has no effect, a system Python interpreter is always used in `uv venv`");
warn_user_once!(
"The `--system` flag has no effect, a system Python interpreter is always used in `uv venv`"
);
}
// Resolve the settings from the command-line arguments and workspace configuration.

View file

@ -506,18 +506,26 @@ impl ToolRunSettings {
// If `--upgrade` was passed explicitly, warn.
if installer.upgrade || !installer.upgrade_package.is_empty() {
if with.is_empty() && with_requirements.is_empty() {
warn_user_once!("Tools cannot be upgraded via `{invocation_source}`; use `uv tool upgrade --all` to upgrade all installed tools, or `{invocation_source} package@latest` to run the latest version of a tool.");
warn_user_once!(
"Tools cannot be upgraded via `{invocation_source}`; use `uv tool upgrade --all` to upgrade all installed tools, or `{invocation_source} package@latest` to run the latest version of a tool."
);
} else {
warn_user_once!("Tools cannot be upgraded via `{invocation_source}`; use `uv tool upgrade --all` to upgrade all installed tools, `{invocation_source} package@latest` to run the latest version of a tool, or `{invocation_source} --refresh package` to upgrade any `--with` dependencies.");
warn_user_once!(
"Tools cannot be upgraded via `{invocation_source}`; use `uv tool upgrade --all` to upgrade all installed tools, `{invocation_source} package@latest` to run the latest version of a tool, or `{invocation_source} --refresh package` to upgrade any `--with` dependencies."
);
}
}
// If `--reinstall` was passed explicitly, warn.
if installer.reinstall || !installer.reinstall_package.is_empty() {
if with.is_empty() && with_requirements.is_empty() {
warn_user_once!("Tools cannot be reinstalled via `{invocation_source}`; use `uv tool upgrade --all --reinstall` to reinstall all installed tools, or `{invocation_source} package@latest` to run the latest version of a tool.");
warn_user_once!(
"Tools cannot be reinstalled via `{invocation_source}`; use `uv tool upgrade --all --reinstall` to reinstall all installed tools, or `{invocation_source} package@latest` to run the latest version of a tool."
);
} else {
warn_user_once!("Tools cannot be reinstalled via `{invocation_source}`; use `uv tool upgrade --all --reinstall` to reinstall all installed tools, `{invocation_source} package@latest` to run the latest version of a tool, or `{invocation_source} --refresh package` to reinstall any `--with` dependencies.");
warn_user_once!(
"Tools cannot be reinstalled via `{invocation_source}`; use `uv tool upgrade --all --reinstall` to reinstall all installed tools, `{invocation_source} package@latest` to run the latest version of a tool, or `{invocation_source} --refresh package` to reinstall any `--with` dependencies."
);
}
}
@ -1334,9 +1342,13 @@ impl AddSettings {
.is_some_and(Maybe::is_some)
{
if script.is_some() {
warn_user_once!("Indexes specified via `--index-url` will not be persisted to the script; use `--default-index` instead.");
warn_user_once!(
"Indexes specified via `--index-url` will not be persisted to the script; use `--default-index` instead."
);
} else {
warn_user_once!("Indexes specified via `--index-url` will not be persisted to the `pyproject.toml` file; use `--default-index` instead.");
warn_user_once!(
"Indexes specified via `--index-url` will not be persisted to the `pyproject.toml` file; use `--default-index` instead."
);
}
}
@ -1347,9 +1359,13 @@ impl AddSettings {
.is_some_and(|extra_index_url| extra_index_url.iter().any(Maybe::is_some))
{
if script.is_some() {
warn_user_once!("Indexes specified via `--extra-index-url` will not be persisted to the script; use `--index` instead.");
warn_user_once!(
"Indexes specified via `--extra-index-url` will not be persisted to the script; use `--index` instead."
);
} else {
warn_user_once!("Indexes specified via `--extra-index-url` will not be persisted to the `pyproject.toml` file; use `--index` instead.");
warn_user_once!(
"Indexes specified via `--extra-index-url` will not be persisted to the `pyproject.toml` file; use `--index` instead."
);
}
}

View file

@ -2238,7 +2238,9 @@ fn install_git_private_https_pat_at_ref() {
""
};
let package = format!("uv-private-pypackage @ git+https://{user}{token}@github.com/astral-test/uv-private-pypackage@6c09ce9ae81f50670a60abd7d95f30dd416d00ac");
let package = format!(
"uv-private-pypackage @ git+https://{user}{token}@github.com/astral-test/uv-private-pypackage@6c09ce9ae81f50670a60abd7d95f30dd416d00ac"
);
uv_snapshot!(filters, context.pip_install()
.arg(package), @r###"
success: true

View file

@ -1087,7 +1087,10 @@ fn install_local_wheel() -> Result<()> {
// Download a wheel.
let archive = context.temp_dir.child("tomli-2.0.1-py3-none-any.whl");
download_to_disk("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", &archive);
download_to_disk(
"https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl",
&archive,
);
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str(&format!(
@ -1224,7 +1227,10 @@ fn mismatched_version() -> Result<()> {
// Download a wheel.
let archive = context.temp_dir.child("tomli-3.7.2-py3-none-any.whl");
download_to_disk("https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", &archive);
download_to_disk(
"https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl",
&archive,
);
let requirements_txt = context.temp_dir.child("requirements.txt");
requirements_txt.write_str(&format!(