use let chains in various crates (#19908)

Now that uv’s MSRV is Rust 1.94, use Rust 2024 let chains where they
make nested guards clearer in the parser, configuration, and data-model
crates.

This flattens related pattern matches and predicates while preserving
evaluation order, short-circuiting, borrow scopes, and mutation
behavior. Guards involving effects, staged work, or non-obvious
lifetimes remain nested.
This commit is contained in:
Zsolt Dollenstein
2026-06-18 17:47:27 +01:00
committed by GitHub
parent ac8a4615da
commit 14855e023d
22 changed files with 354 additions and 377 deletions
+4 -4
View File
@@ -17,10 +17,10 @@ impl Constraints {
let mut constraints: FxHashMap<PackageName, Vec<Requirement>> = FxHashMap::default();
for requirement in requirements {
// Skip empty constraints.
if let RequirementSource::Registry { specifier, .. } = &requirement.source {
if specifier.is_empty() {
continue;
}
if let RequirementSource::Registry { specifier, .. } = &requirement.source
&& specifier.is_empty()
{
continue;
}
constraints
+20 -26
View File
@@ -87,10 +87,10 @@ impl InstallOptions {
// If `--only-install-workspace` is set, only include the project and workspace members.
if self.only_install_workspace {
// Check if it's the project itself
if let Some(project_name) = project_name {
if package_name == project_name {
return true;
}
if let Some(project_name) = project_name
&& package_name == project_name
{
return true;
}
// Check if it's a workspace member
@@ -105,25 +105,22 @@ impl InstallOptions {
// If `--only-install-project` is set, only include the project itself.
if self.only_install_project {
if let Some(project_name) = project_name {
if package_name == project_name {
return true;
}
if let Some(project_name) = project_name
&& package_name == project_name
{
return true;
}
debug!("Omitting `{package_name}` from resolution due to `--only-install-project`");
return false;
}
// If `--no-install-project` is set, remove the project itself.
if self.no_install_project {
if let Some(project_name) = project_name {
if package_name == project_name {
debug!(
"Omitting `{package_name}` from resolution due to `--no-install-project`"
);
return false;
}
}
if self.no_install_project
&& let Some(project_name) = project_name
&& package_name == project_name
{
debug!("Omitting `{package_name}` from resolution due to `--no-install-project`");
return false;
}
// If `--no-install-workspace` is set, remove the project and any workspace members.
@@ -131,15 +128,12 @@ impl InstallOptions {
// In some cases, the project root might be omitted from the list of workspace members
// encoded in the lockfile. (But we already checked this above if `--no-install-project`
// is set.)
if !self.no_install_project {
if let Some(project_name) = project_name {
if package_name == project_name {
debug!(
"Omitting `{package_name}` from resolution due to `--no-install-workspace`"
);
return false;
}
}
if !self.no_install_project
&& let Some(project_name) = project_name
&& package_name == project_name
{
debug!("Omitting `{package_name}` from resolution due to `--no-install-workspace`");
return false;
}
if members.contains(package_name) {
@@ -190,10 +190,10 @@ impl Upgrade {
let mut constraints: FxHashMap<PackageName, Vec<Requirement>> = FxHashMap::default();
for requirement in upgrade_package {
// Skip any "empty" constraints.
if let RequirementSource::Registry { specifier, .. } = &requirement.source {
if specifier.is_empty() {
continue;
}
if let RequirementSource::Registry { specifier, .. } = &requirement.source
&& specifier.is_empty()
{
continue;
}
constraints
.entry(requirement.name.clone())
+22 -22
View File
@@ -503,10 +503,10 @@ impl Index {
/// Resolve the index relative to the given root directory.
pub fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
if let IndexUrl::Path(ref url) = self.url {
if let Some(given) = url.given() {
self.url = IndexUrl::parse(given, Some(root_dir))?;
}
if let IndexUrl::Path(ref url) = self.url
&& let Some(given) = url.given()
{
self.url = IndexUrl::parse(given, Some(root_dir))?;
}
Ok(self)
}
@@ -565,24 +565,24 @@ impl FromStr for Index {
fn from_str(s: &str) -> Result<Self, Self::Err> {
// Determine whether the source is prefixed with a name, as in `name=https://pypi.org/simple`.
if let Some((name, url)) = s.split_once('=') {
if !name.chars().any(|c| c == ':') {
let name = IndexName::from_str(name)?;
let url = IndexUrl::from_str(url)?;
return Ok(Self {
name: Some(name),
url,
explicit: false,
default: false,
origin: None,
format: IndexFormat::Simple,
publish_url: None,
authenticate: AuthPolicy::default(),
ignore_error_codes: None,
cache_control: None,
exclude_newer: None,
});
}
if let Some((name, url)) = s.split_once('=')
&& !name.chars().any(|c| c == ':')
{
let name = IndexName::from_str(name)?;
let url = IndexUrl::from_str(url)?;
return Ok(Self {
name: Some(name),
url,
explicit: false,
default: false,
origin: None,
format: IndexFormat::Simple,
publish_url: None,
authenticate: AuthPolicy::default(),
ignore_error_codes: None,
cache_control: None,
exclude_newer: None,
});
}
// Otherwise, assume the source is a URL.
+11 -11
View File
@@ -121,17 +121,17 @@ impl IndexUrl {
return;
};
if let Some(path) = verbatim_url.given() {
if !is_disambiguated_path(path) {
if cfg!(windows) {
warn_user!(
"Relative paths passed to `--index` or `--default-index` should be disambiguated from index names (use `.\\{path}` or `./{path}`). Support for ambiguous values will be removed in the future"
);
} else {
warn_user!(
"Relative paths passed to `--index` or `--default-index` should be disambiguated from index names (use `./{path}`). Support for ambiguous values will be removed in the future"
);
}
if let Some(path) = verbatim_url.given()
&& !is_disambiguated_path(path)
{
if cfg!(windows) {
warn_user!(
"Relative paths passed to `--index` or `--default-index` should be disambiguated from index names (use `.\\{path}` or `./{path}`). Support for ambiguous values will be removed in the future"
);
} else {
warn_user!(
"Relative paths passed to `--index` or `--default-index` should be disambiguated from index names (use `./{path}`). Support for ambiguous values will be removed in the future"
);
}
}
}
@@ -67,16 +67,16 @@ impl LoweredRequirement {
sources
.iter()
.filter(|source| {
if let Some(target) = source.extra() {
if extra != Some(target) {
return false;
}
if let Some(target) = source.extra()
&& extra != Some(target)
{
return false;
}
if let Some(target) = source.group() {
if group != Some(target) {
return false;
}
if let Some(target) = source.group()
&& group != Some(target)
{
return false;
}
true
+6 -8
View File
@@ -55,14 +55,12 @@ fn get_doc_comment(attrs: &[Attribute]) -> String {
attrs
.iter()
.filter_map(|attr| {
if attr.path().is_ident("doc") {
if let syn::Meta::NameValue(meta) = &attr.meta {
if let syn::Expr::Lit(expr) = &meta.value {
if let syn::Lit::Str(str) = &expr.lit {
return Some(str.value().trim().to_string());
}
}
}
if attr.path().is_ident("doc")
&& let syn::Meta::NameValue(meta) = &attr.meta
&& let syn::Expr::Lit(expr) = &meta.value
&& let syn::Lit::Str(str) = &expr.lit
{
return Some(str.value().trim().to_string());
}
None
})
+16 -19
View File
@@ -49,14 +49,14 @@ pub(crate) fn derive_impl(input: DeriveInput) -> syn::Result<TokenStream> {
// by calling `Type::record` instead of `visitor.visit_set`
if let (Type::Path(ty), Meta::List(list)) = (&field.ty, &serde.meta) {
for token in list.tokens.clone() {
if let TokenTree::Ident(ident) = token {
if ident == "flatten" {
output.push(quote_spanned!(
ty.span() => (<#ty>::record(visit))
));
if let TokenTree::Ident(ident) = token
&& ident == "flatten"
{
output.push(quote_spanned!(
ty.span() => (<#ty>::record(visit))
));
break;
}
break;
}
}
}
@@ -361,18 +361,15 @@ fn parse_deprecated_attribute(attribute: &Attribute) -> syn::Result<DeprecatedAt
}
fn get_inner_type_if_option(ty: &Type) -> Option<&Type> {
if let Type::Path(type_path) = ty {
if type_path.path.segments.len() == 1 && type_path.path.segments[0].ident == "Option" {
if let PathArguments::AngleBracketed(angle_bracketed_args) =
&type_path.path.segments[0].arguments
{
if angle_bracketed_args.args.len() == 1 {
if let GenericArgument::Type(inner_type) = &angle_bracketed_args.args[0] {
return Some(inner_type);
}
}
}
}
if let Type::Path(type_path) = ty
&& type_path.path.segments.len() == 1
&& type_path.path.segments[0].ident == "Option"
&& let PathArguments::AngleBracketed(angle_bracketed_args) =
&type_path.path.segments[0].arguments
&& angle_bracketed_args.args.len() == 1
&& let GenericArgument::Type(inner_type) = &angle_bracketed_args.args[0]
{
return Some(inner_type);
}
None
}
+5 -5
View File
@@ -741,11 +741,11 @@ impl Version {
});
} else {
// Either bump the matching kind or set to 1
if let Some(prerelease) = &mut full.pre {
if prerelease.kind == kind {
prerelease.number += 1;
return;
}
if let Some(prerelease) = &mut full.pre
&& prerelease.kind == kind
{
prerelease.number += 1;
return;
}
full.pre = Some(Prerelease { kind, number: 1 });
}
+17 -18
View File
@@ -1051,21 +1051,20 @@ impl MarkerTree {
CanonicalMarkerValueString::PlatformRelease
| CanonicalMarkerValueString::PlatformVersion
) && range.as_singleton().is_none()
&& let Some((start, end)) = range.bounding_range()
{
if let Some((start, end)) = range.bounding_range() {
if let Bound::Included(value) | Bound::Excluded(value) = start {
reporter.report(
MarkerWarningKind::LexicographicComparison,
format!("Comparing {l_string} and {value} lexicographically"),
);
}
if let Bound::Included(value) | Bound::Excluded(value) = start {
reporter.report(
MarkerWarningKind::LexicographicComparison,
format!("Comparing {l_string} and {value} lexicographically"),
);
}
if let Bound::Included(value) | Bound::Excluded(value) = end {
reporter.report(
MarkerWarningKind::LexicographicComparison,
format!("Comparing {l_string} and {value} lexicographically"),
);
}
if let Bound::Included(value) | Bound::Excluded(value) = end {
reporter.report(
MarkerWarningKind::LexicographicComparison,
format!("Comparing {l_string} and {value} lexicographically"),
);
}
}
@@ -1201,11 +1200,11 @@ impl MarkerTree {
/// main conjunction.
pub fn top_level_extra_name(self) -> Option<Cow<'static, ExtraName>> {
// Fast path: The marker is only a `extra == "..."`.
if let MarkerTreeKind::Extra(marker) = self.kind() {
if marker.edge(true).is_true() {
let CanonicalMarkerValueExtra::Extra(extra) = marker.name;
return Some(Cow::Borrowed(extra));
}
if let MarkerTreeKind::Extra(marker) = self.kind()
&& marker.edge(true).is_true()
{
let CanonicalMarkerValueExtra::Extra(extra) = marker.name;
return Some(Cow::Borrowed(extra));
}
let extra_expression = self.top_level_extra()?;
+8 -8
View File
@@ -822,14 +822,14 @@ impl FromStr for PlatformTag {
});
}
if let Some(release_arch) = rest.strip_suffix("_64bit") {
if !release_arch.is_empty() {
return Ok(Self::Solaris {
release_arch: release_arch.parse::<ReleaseArch>().map_err(|_| {
ParsePlatformTagError::InvalidCharacters { tag: s.to_string() }
})?,
});
}
if let Some(release_arch) = rest.strip_suffix("_64bit")
&& !release_arch.is_empty()
{
return Ok(Self::Solaris {
release_arch: release_arch.parse::<ReleaseArch>().map_err(|_| {
ParsePlatformTagError::InvalidCharacters { tag: s.to_string() }
})?,
});
}
return Err(ParsePlatformTagError::InvalidArch {
+4 -4
View File
@@ -140,10 +140,10 @@ impl Conflicts {
for (group, specifiers) in groups {
if let Some(includer) = group_node_idxs.get(group) {
for specifier in specifiers {
if let DependencyGroupSpecifier::IncludeGroup { include_group } = specifier {
if let Some(included) = group_node_idxs.get(include_group) {
graph.add_edge(*included, *includer, ());
}
if let DependencyGroupSpecifier::IncludeGroup { include_group } = specifier
&& let Some(included) = group_node_idxs.get(include_group)
{
graph.add_edge(*included, *includer, ());
}
}
}
+26 -28
View File
@@ -1216,10 +1216,10 @@ fn find_python_installations_with_strategy<'a>(
})
}
PythonRequest::Key(request) => {
if let Some(version) = request.version() {
if let Err(err) = version.check_supported() {
return Box::new(iter::once(Err(Error::InvalidVersionRequest(err))));
}
if let Some(version) = request.version()
&& let Err(err) = version.check_supported()
{
return Box::new(iter::once(Err(Error::InvalidVersionRequest(err))));
}
Box::new({
@@ -1292,10 +1292,10 @@ pub(crate) fn find_python_installation(
// Iterate until the first critical error or happy result
if !result.as_ref().err().is_none_or(Error::is_critical) {
// Track the first non-critical error
if first_error.is_none() {
if let Err(err) = result {
first_error = Some(err);
}
if first_error.is_none()
&& let Err(err) = result
{
first_error = Some(err);
}
continue;
}
@@ -2711,12 +2711,11 @@ impl VersionRequest {
/// If the specifiers consist of a single `==` constraint, the version is parsed as a
/// concrete version request (e.g., `MajorMinorPatch`) rather than a range.
pub fn from_specifiers(specifiers: VersionSpecifiers, variant: PythonVariant) -> Self {
if let [specifier] = specifiers.iter().as_slice() {
if specifier.operator() == &uv_pep440::Operator::Equal {
if let Ok(request) = Self::from_str(&specifier.version().to_string()) {
return request;
}
}
if let [specifier] = specifiers.iter().as_slice()
&& specifier.operator() == &uv_pep440::Operator::Equal
&& let Ok(request) = Self::from_str(&specifier.version().to_string())
{
return request;
}
Self::Range(specifiers, variant)
}
@@ -2820,12 +2819,12 @@ impl VersionRequest {
}
// Include free-threaded variants
if let Some(variant) = self.variant() {
if variant != PythonVariant::Default {
for i in 0..names.len() {
let name = names[i].with_variant(variant);
names.push(name);
}
if let Some(variant) = self.variant()
&& variant != PythonVariant::Default
{
for i in 0..names.len() {
let name = names[i].with_variant(variant);
names.push(name);
}
}
@@ -2928,14 +2927,13 @@ impl VersionRequest {
Self::Range(_, _) => (),
}
if self.is_freethreaded() {
if let Self::MajorMinor(major, minor, _) = self.clone().without_patch() {
if (major, minor) < (3, 13) {
return Err(format!(
"Python <3.13 does not support free-threading but {self} was requested."
));
}
}
if self.is_freethreaded()
&& let Self::MajorMinor(major, minor, _) = self.clone().without_patch()
&& (major, minor) < (3, 13)
{
return Err(format!(
"Python <3.13 does not support free-threading but {self} was requested."
));
}
Ok(())
+40 -41
View File
@@ -236,22 +236,22 @@ pub struct PlatformRequest {
impl PlatformRequest {
/// Check if this platform request is satisfied by a platform.
pub(crate) fn matches(&self, platform: &Platform) -> bool {
if let Some(os) = self.os {
if !platform.os.supports(os) {
return false;
}
if let Some(os) = self.os
&& !platform.os.supports(os)
{
return false;
}
if let Some(arch) = self.arch {
if !arch.satisfied_by(platform) {
return false;
}
if let Some(arch) = self.arch
&& !arch.satisfied_by(platform)
{
return false;
}
if let Some(libc) = self.libc {
if platform.libc != libc {
return false;
}
if let Some(libc) = self.libc
&& platform.libc != libc
{
return false;
}
true
@@ -555,10 +555,10 @@ impl PythonDownloadRequest {
return false;
}
if let Some(implementation) = &self.implementation {
if key.implementation != LenientImplementationName::from(*implementation) {
return false;
}
if let Some(implementation) = &self.implementation
&& key.implementation != LenientImplementationName::from(*implementation)
{
return false;
}
// If we don't allow pre-releases, don't match a key with a pre-release tag
if !self.allows_prereleases() && key.prerelease.is_some() {
@@ -573,10 +573,10 @@ impl PythonDownloadRequest {
) {
return false;
}
if let Some(variant) = version.variant() {
if variant != key.variant {
return false;
}
if let Some(variant) = version.variant()
&& variant != key.variant
{
return false;
}
}
true
@@ -634,14 +634,14 @@ impl PythonDownloadRequest {
pub(crate) fn satisfied_by_interpreter(&self, interpreter: &Interpreter) -> bool {
let executable = interpreter.sys_executable().display();
if let Some(version) = self.version() {
if !version.matches_interpreter(interpreter) {
let interpreter_version = interpreter.python_version();
debug!(
"Skipping interpreter at `{executable}`: version `{interpreter_version}` does not match request `{version}`"
);
return false;
}
if let Some(version) = self.version()
&& !version.matches_interpreter(interpreter)
{
let interpreter_version = interpreter.python_version();
debug!(
"Skipping interpreter at `{executable}`: version `{interpreter_version}` does not match request `{version}`"
);
return false;
}
let platform = self.platform();
let interpreter_platform = Platform::from(interpreter.platform());
@@ -651,14 +651,14 @@ impl PythonDownloadRequest {
);
return false;
}
if let Some(implementation) = self.implementation() {
if !implementation.matches_interpreter(interpreter) {
debug!(
"Skipping interpreter at `{executable}`: implementation `{}` does not match request `{implementation}`",
interpreter.implementation_name(),
);
return false;
}
if let Some(implementation) = self.implementation()
&& !implementation.matches_interpreter(interpreter)
{
debug!(
"Skipping interpreter at `{executable}`: implementation `{}` does not match request `{implementation}`",
interpreter.implementation_name(),
);
return false;
}
true
}
@@ -997,13 +997,12 @@ impl ManagedPythonDownloadList {
return Ok(download);
}
if !request.allows_prereleases() {
if let Some(download) = self
if !request.allows_prereleases()
&& let Some(download) = self
.iter_matching(&request.clone().with_prereleases(true))
.next()
{
return Ok(download);
}
{
return Ok(download);
}
Err(Error::NoDownloadFound(request.clone()))
+18 -18
View File
@@ -52,26 +52,26 @@ impl FromStr for PythonVersion {
if version.epoch() != 0 {
return Err(format!("Python version `{s}` has a non-zero epoch"));
}
if let Some(major) = version.release().first() {
if u8::try_from(*major).is_err() {
return Err(format!(
"Python version `{s}` has an invalid major version ({major})"
));
}
if let Some(major) = version.release().first()
&& u8::try_from(*major).is_err()
{
return Err(format!(
"Python version `{s}` has an invalid major version ({major})"
));
}
if let Some(minor) = version.release().get(1) {
if u8::try_from(*minor).is_err() {
return Err(format!(
"Python version `{s}` has an invalid minor version ({minor})"
));
}
if let Some(minor) = version.release().get(1)
&& u8::try_from(*minor).is_err()
{
return Err(format!(
"Python version `{s}` has an invalid minor version ({minor})"
));
}
if let Some(patch) = version.release().get(2) {
if u8::try_from(*patch).is_err() {
return Err(format!(
"Python version `{s}` has an invalid patch version ({patch})"
));
}
if let Some(patch) = version.release().get(2)
&& u8::try_from(*patch).is_err()
{
return Err(format!(
"Python version `{s}` has an invalid patch version ({patch})"
));
}
Ok(Self(version))
+6 -6
View File
@@ -317,12 +317,12 @@ impl PyVenvConfiguration {
let mut lines = content.lines().map(Cow::Borrowed).collect::<Vec<_>>();
let mut found = false;
for line in &mut lines {
if let Some((lhs, _)) = line.split_once('=') {
if lhs.trim() == key {
*line = Cow::Owned(format!("{key} = {value}"));
found = true;
break;
}
if let Some((lhs, _)) = line.split_once('=')
&& lhs.trim() == key
{
*line = Cow::Owned(format!("{key} = {value}"));
found = true;
break;
}
}
if !found {
+18 -18
View File
@@ -565,12 +565,12 @@ impl RequirementsSpecification {
}
if let Some(index_url) = source.index_url {
if let Some(existing) = spec.index_url {
if CanonicalUrl::new(index_url.url()) != CanonicalUrl::new(existing.url()) {
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs. `{index_url}`",
));
}
if let Some(existing) = spec.index_url
&& CanonicalUrl::new(index_url.url()) != CanonicalUrl::new(existing.url())
{
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs. `{index_url}`",
));
}
spec.index_url = Some(index_url);
}
@@ -603,12 +603,12 @@ impl RequirementsSpecification {
spec.constraints.extend(source.constraints);
if let Some(index_url) = source.index_url {
if let Some(existing) = spec.index_url {
if CanonicalUrl::new(index_url.url()) != CanonicalUrl::new(existing.url()) {
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs. `{index_url}`",
));
}
if let Some(existing) = spec.index_url
&& CanonicalUrl::new(index_url.url()) != CanonicalUrl::new(existing.url())
{
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs. `{index_url}`",
));
}
spec.index_url = Some(index_url);
}
@@ -627,12 +627,12 @@ impl RequirementsSpecification {
spec.overrides.extend(source.overrides);
if let Some(index_url) = source.index_url {
if let Some(existing) = spec.index_url {
if CanonicalUrl::new(index_url.url()) != CanonicalUrl::new(existing.url()) {
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs. `{index_url}`",
));
}
if let Some(existing) = spec.index_url
&& CanonicalUrl::new(index_url.url()) != CanonicalUrl::new(existing.url())
{
return Err(anyhow::anyhow!(
"Multiple index URLs specified: `{existing}` vs. `{index_url}`",
));
}
spec.index_url = Some(index_url);
}
+32 -34
View File
@@ -190,23 +190,22 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
}
// Read Poetry-specific metadata from the `pyproject.toml`.
if let Some(tool) = pyproject.tool {
if let Some(poetry) = tool.poetry {
if let Some(name) = poetry.name {
debug!(
"Found Poetry metadata for {path} in `pyproject.toml` ({name})",
path = parsed_directory_url.install_path.display(),
name = name
);
return Ok(uv_pep508::Requirement {
name,
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
origin: requirement.origin,
});
}
}
if let Some(tool) = pyproject.tool
&& let Some(poetry) = tool.poetry
&& let Some(name) = poetry.name
{
debug!(
"Found Poetry metadata for {path} in `pyproject.toml` ({name})",
path = parsed_directory_url.install_path.display(),
name = name
);
return Ok(uv_pep508::Requirement {
name,
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
origin: requirement.origin,
});
}
}
@@ -220,23 +219,22 @@ impl<'a, Context: BuildContext> NamedRequirementsResolver<'a, Context> {
ini.read(contents).ok()
})
{
if let Some(section) = setup_cfg.get("metadata") {
if let Some(Some(name)) = section.get("name") {
if let Ok(name) = PackageName::from_str(name) {
debug!(
"Found setuptools metadata for {path} in `setup.cfg` ({name})",
path = parsed_directory_url.install_path.display(),
name = name
);
return Ok(uv_pep508::Requirement {
name,
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
origin: requirement.origin,
});
}
}
if let Some(section) = setup_cfg.get("metadata")
&& let Some(Some(name)) = section.get("name")
&& let Ok(name) = PackageName::from_str(name)
{
debug!(
"Found setuptools metadata for {path} in `setup.cfg` ({name})",
path = parsed_directory_url.install_path.display(),
name = name
);
return Ok(uv_pep508::Requirement {
name,
extras: requirement.extras,
version_or_url: Some(VersionOrUrl::Url(requirement.url)),
marker: requirement.marker,
origin: requirement.origin,
});
}
}
+15 -17
View File
@@ -123,14 +123,12 @@ impl CandidateSelector {
};
// If we're not upgrading, we should prefer the already-installed distribution.
if !upgrade {
if let Some(installed) = installed {
trace!(
"Using installed {} {} that satisfies {range}",
installed.name, installed.version
);
return Some(installed);
}
if !upgrade && let Some(installed) = installed {
trace!(
"Using installed {} {} that satisfies {range}",
installed.name, installed.version
);
return Some(installed);
}
// Otherwise, find the best candidate from the version maps.
@@ -140,21 +138,21 @@ impl CandidateSelector {
//
// If the already-installed version is _more_ compatible than the best candidate
// from the version maps, use the installed version.
if let Some(installed) = installed {
if compatible.as_ref().is_none_or(|compatible| {
if let Some(installed) = installed
&& compatible.as_ref().is_none_or(|compatible| {
let highest = self.use_highest_version(package_name, env);
if highest {
installed.version() >= compatible.version()
} else {
installed.version() <= compatible.version()
}
}) {
trace!(
"Using installed {} {} that satisfies {range}",
installed.name, installed.version
);
return Some(installed);
}
})
{
trace!(
"Using installed {} {} that satisfies {range}",
installed.name, installed.version
);
return Some(installed);
}
compatible
+26 -26
View File
@@ -1671,32 +1671,32 @@ impl Source {
|| rev.is_some()
|| matches!(lfs, GitLfsSetting::Enabled { .. }))
{
if let Some(sources) = existing_sources {
if let Some(package_sources) = sources.get(name) {
for existing_source in package_sources.iter() {
if let Self::Git {
git,
subdirectory,
path,
marker,
extra,
group,
..
} = existing_source
{
return Ok(Some(Self::Git {
git: git.clone(),
subdirectory: subdirectory.clone(),
rev,
tag,
branch,
lfs: lfs.into(),
marker: *marker,
path: path.clone(),
extra: extra.clone(),
group: group.clone(),
}));
}
if let Some(sources) = existing_sources
&& let Some(package_sources) = sources.get(name)
{
for existing_source in package_sources.iter() {
if let Self::Git {
git,
subdirectory,
path,
marker,
extra,
group,
..
} = existing_source
{
return Ok(Some(Self::Git {
git: git.clone(),
subdirectory: subdirectory.clone(),
rev,
tag,
branch,
lfs: lfs.into(),
marker: *marker,
path: path.clone(),
extra: extra.clone(),
group: group.clone(),
}));
}
}
}
+30 -33
View File
@@ -450,14 +450,13 @@ impl PyProjectTomlMut {
.iter()
.find(|table| {
// If the index has the same name, reuse it.
if let Some(index) = index.name.as_deref() {
if table
if let Some(index) = index.name.as_deref()
&& table
.get("name")
.and_then(|name| name.as_str())
.is_some_and(|name| name == index)
{
return true;
}
{
return true;
}
// If the index is the default, and there's another default index, reuse it.
@@ -487,23 +486,22 @@ impl PyProjectTomlMut {
.unwrap_or_default();
// If necessary, update the name.
if let Some(index) = index.name.as_deref() {
if table
if let Some(index) = index.name.as_deref()
&& table
.get("name")
.and_then(|name| name.as_str())
.is_none_or(|name| name != index)
{
let mut formatted = Formatted::new(index.to_string());
if let Some(value) = table.get("name").and_then(Item::as_value) {
if let Some(prefix) = value.decor().prefix() {
formatted.decor_mut().set_prefix(prefix.clone());
}
if let Some(suffix) = value.decor().suffix() {
formatted.decor_mut().set_suffix(suffix.clone());
}
{
let mut formatted = Formatted::new(index.to_string());
if let Some(value) = table.get("name").and_then(Item::as_value) {
if let Some(prefix) = value.decor().prefix() {
formatted.decor_mut().set_prefix(prefix.clone());
}
if let Some(suffix) = value.decor().suffix() {
formatted.decor_mut().set_suffix(suffix.clone());
}
table.insert("name", Value::String(formatted).into());
}
table.insert("name", Value::String(formatted).into());
}
// If necessary, update the URL.
@@ -547,14 +545,13 @@ impl PyProjectTomlMut {
// Remove any replaced tables.
existing.retain(|table| {
// If the index has the same name, skip it.
if let Some(index) = index.name.as_deref() {
if table
if let Some(index) = index.name.as_deref()
&& table
.get("name")
.and_then(|name| name.as_str())
.is_some_and(|name| name == index)
{
return false;
}
{
return false;
}
// If there's another default index, skip it.
@@ -1168,10 +1165,10 @@ impl PyProjectTomlMut {
if let Some(project) = self.doc.get("project").and_then(Item::as_table) {
// Check `project.dependencies`.
if let Some(dependencies) = project.get("dependencies").and_then(Item::as_array) {
if !find_dependencies(name, marker, dependencies).is_empty() {
types.push(DependencyType::Production);
}
if let Some(dependencies) = project.get("dependencies").and_then(Item::as_array)
&& !find_dependencies(name, marker, dependencies).is_empty()
{
types.push(DependencyType::Production);
}
// Check `project.optional-dependencies`.
@@ -1219,10 +1216,9 @@ impl PyProjectTomlMut {
.and_then(Item::as_table)
.and_then(|uv| uv.get("dev-dependencies"))
.and_then(Item::as_array)
&& !find_dependencies(name, marker, dev_dependencies).is_empty()
{
if !find_dependencies(name, marker, dev_dependencies).is_empty() {
types.push(DependencyType::Dev);
}
types.push(DependencyType::Dev);
}
types
@@ -1648,10 +1644,11 @@ fn find_dependencies(
) -> Vec<(usize, Requirement)> {
let mut to_replace = Vec::new();
for (i, dep) in deps.iter().enumerate() {
if let Some(req) = dep.as_str().and_then(try_parse_requirement) {
if marker.is_none_or(|m| *m == req.marker) && *name == req.name {
to_replace.push((i, req));
}
if let Some(req) = dep.as_str().and_then(try_parse_requirement)
&& marker.is_none_or(|m| *m == req.marker)
&& *name == req.name
{
to_replace.push((i, req));
}
}
to_replace
+18 -19
View File
@@ -664,17 +664,16 @@ impl Workspace {
/// Returns the set of conflicts for the workspace.
pub fn conflicts(&self) -> Result<Conflicts, WorkspaceError> {
let mut conflicting = Conflicts::empty();
if self.is_non_project() {
if let Some(root_conflicts) = self
if self.is_non_project()
&& let Some(root_conflicts) = self
.pyproject_toml
.tool
.as_ref()
.and_then(|tool| tool.uv.as_ref())
.and_then(|uv| uv.conflicts.as_ref())
{
let mut root_conflicts = root_conflicts.to_conflicts()?;
conflicting.append(&mut root_conflicts);
}
{
let mut root_conflicts = root_conflicts.to_conflicts()?;
conflicting.append(&mut root_conflicts);
}
for member in self.packages.values() {
conflicting.append(&mut member.pyproject_toml.conflicts()?);
@@ -979,20 +978,20 @@ impl Workspace {
let mut workspace_members = Arc::new(workspace_members);
// For the cases such as `MemberDiscovery::None`, add the current project if missing.
if let Some(root_member) = current_project {
if !workspace_members.contains_key(&root_member.project.name) {
assert!(matches!(
options.members,
MemberDiscovery::None | MemberDiscovery::Ignore(_)
));
debug!(
"Adding current workspace member: `{}`",
root_member.root.simplified_display()
);
if let Some(root_member) = current_project
&& !workspace_members.contains_key(&root_member.project.name)
{
assert!(matches!(
options.members,
MemberDiscovery::None | MemberDiscovery::Ignore(_)
));
debug!(
"Adding current workspace member: `{}`",
root_member.root.simplified_display()
);
Arc::make_mut(&mut workspace_members)
.insert(root_member.project.name.clone(), root_member);
}
Arc::make_mut(&mut workspace_members)
.insert(root_member.project.name.clone(), root_member);
}
let workspace_sources = workspace_pyproject_toml