Skip to content

Commit f267e59

Browse files
committed
Reverts
1 parent b21c3d0 commit f267e59

File tree

7 files changed

+82
-64
lines changed

7 files changed

+82
-64
lines changed

crates/platform-tags/src/tags.rs

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -203,34 +203,33 @@ impl Tags {
203203
wheel_abi_tags: &[String],
204204
wheel_platform_tags: &[String],
205205
) -> TagCompatibility {
206-
return TagCompatibility::Compatible(TagPriority(NonZeroU32::new(1).unwrap()));
207-
// let mut max_compatibility = TagCompatibility::Incompatible(IncompatibleTag::Invalid);
208-
//
209-
// for wheel_py in wheel_python_tags {
210-
// let Some(abis) = self.map.get(wheel_py) else {
211-
// max_compatibility =
212-
// max_compatibility.max(TagCompatibility::Incompatible(IncompatibleTag::Python));
213-
// continue;
214-
// };
215-
// for wheel_abi in wheel_abi_tags {
216-
// let Some(platforms) = abis.get(wheel_abi) else {
217-
// max_compatibility =
218-
// max_compatibility.max(TagCompatibility::Incompatible(IncompatibleTag::Abi));
219-
// continue;
220-
// };
221-
// for wheel_platform in wheel_platform_tags {
222-
// let priority = platforms.get(wheel_platform).copied();
223-
// if let Some(priority) = priority {
224-
// max_compatibility =
225-
// max_compatibility.max(TagCompatibility::Compatible(priority));
226-
// } else {
227-
// max_compatibility = max_compatibility
228-
// .max(TagCompatibility::Incompatible(IncompatibleTag::Platform));
229-
// }
230-
// }
231-
// }
232-
// }
233-
// max_compatibility
206+
let mut max_compatibility = TagCompatibility::Incompatible(IncompatibleTag::Invalid);
207+
208+
for wheel_py in wheel_python_tags {
209+
let Some(abis) = self.map.get(wheel_py) else {
210+
max_compatibility =
211+
max_compatibility.max(TagCompatibility::Incompatible(IncompatibleTag::Python));
212+
continue;
213+
};
214+
for wheel_abi in wheel_abi_tags {
215+
let Some(platforms) = abis.get(wheel_abi) else {
216+
max_compatibility =
217+
max_compatibility.max(TagCompatibility::Incompatible(IncompatibleTag::Abi));
218+
continue;
219+
};
220+
for wheel_platform in wheel_platform_tags {
221+
let priority = platforms.get(wheel_platform).copied();
222+
if let Some(priority) = priority {
223+
max_compatibility =
224+
max_compatibility.max(TagCompatibility::Compatible(priority));
225+
} else {
226+
max_compatibility = max_compatibility
227+
.max(TagCompatibility::Incompatible(IncompatibleTag::Platform));
228+
}
229+
}
230+
}
231+
}
232+
max_compatibility
234233
}
235234
}
236235

crates/uv-resolver/src/error.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ pub enum ResolveError {
5555
#[error("There are conflicting local versions requested for package `{0}`: {1} vs. {2}")]
5656
ConflictingLocal(PackageName, String, String),
5757

58-
#[error("There are conflicting versions for `{0}`: {1}")]
59-
ConflictingVersions(String, String),
60-
6158
#[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.")]
6259
DisallowedUrl(PackageName, String),
6360

crates/uv-resolver/src/pubgrub/dependencies.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub struct PubGrubDependencies(Vec<(PubGrubPackage, Range<Version>)>);
1919

2020
impl PubGrubDependencies {
2121
/// Generate a set of `PubGrub` dependencies from a set of requirements.
22+
#[allow(clippy::too_many_arguments)]
2223
pub(crate) fn from_requirements(
2324
requirements: &[Requirement],
2425
constraints: &Constraints,
@@ -145,7 +146,7 @@ fn to_pubgrub(
145146
if let [specifier] = specifiers.as_ref() {
146147
if *specifier.operator() == Operator::Equal {
147148
if let Some(expected) = locals.get(&requirement.name) {
148-
return if locals.is_allowed( expected, specifier.version()) {
149+
return if Locals::is_compatible(expected, specifier.version()) {
149150
debug!(
150151
"using local version {expected} for {name} instead of {specifier}",
151152
expected = expected,
@@ -162,7 +163,7 @@ fn to_pubgrub(
162163
expected.to_string(),
163164
specifier.version().to_string(),
164165
))
165-
}
166+
};
166167
}
167168
}
168169
}

crates/uv-resolver/src/resolver/locals.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
1-
use std::ops::Deref;
2-
31
use rustc_hash::FxHashMap;
42

53
use pep440_rs::Version;
6-
use pep508_rs::{MarkerEnvironment, VerbatimUrl, VersionOrUrl};
4+
use pep508_rs::{MarkerEnvironment, VersionOrUrl};
75
use uv_normalize::PackageName;
86

9-
use crate::{Manifest, ResolveError};
7+
use crate::Manifest;
108

119
#[derive(Debug, Default)]
1210
pub(crate) struct Locals {
13-
/// A map of package names to their associated, required URLs.
11+
/// A map of package names to their associated, required local versions.
1412
required: FxHashMap<PackageName, Version>,
1513
}
1614

1715
impl Locals {
18-
pub(crate) fn from_manifest(
19-
manifest: &Manifest,
20-
markers: &MarkerEnvironment,
21-
) -> Result<Self, ResolveError> {
16+
/// Determine the set of permitted local versions in the [`Manifest`].
17+
pub(crate) fn from_manifest(manifest: &Manifest, markers: &MarkerEnvironment) -> Self {
2218
let mut required: FxHashMap<PackageName, Version> = FxHashMap::default();
2319

2420
// Add all direct requirements and constraints. If there are any conflicts, return an error.
@@ -50,16 +46,25 @@ impl Locals {
5046
}
5147
}
5248

53-
Ok(Self { required })
49+
Self { required }
5450
}
5551

5652
/// Return the [`VerbatimUrl`] associated with the given package name, if any.
5753
pub(crate) fn get(&self, package: &PackageName) -> Option<&Version> {
5854
self.required.get(package)
5955
}
6056

61-
/// Returns `true` if a package is allowed to have a local version.
62-
pub(crate) fn is_allowed(&self, expected: &Version, provided: &Version) -> bool {
57+
/// Returns `true` if a provided version is compatible with the expected local version.
58+
///
59+
/// The versions are compatible if they are the same including their local segment, or the
60+
/// same except for the local segment, which is empty in the provided version.
61+
///
62+
/// For example, if the expected version is `1.0.0+local` and the provided version is `1.0.0+other`,
63+
/// this function will return `false`.
64+
///
65+
/// If the expected version is `1.0.0+local` and the provided version is `1.0.0`, the function will
66+
/// return `true`.
67+
pub(crate) fn is_compatible(expected: &Version, provided: &Version) -> bool {
6368
// The requirements should be the same, ignoring local segments.
6469
if expected.clone().without_local() != provided.clone().without_local() {
6570
return false;
@@ -80,7 +85,7 @@ fn to_local(version_or_url: Option<&VersionOrUrl>) -> Option<&Version> {
8085
return None;
8186
};
8287

83-
let [specifier] = specifier.deref() else {
88+
let [specifier] = &**specifier else {
8489
return None;
8590
};
8691

crates/uv-resolver/src/resolver/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl<'a, Provider: ResolverProvider> Resolver<'a, Provider> {
166166
selector: CandidateSelector::for_resolution(options, &manifest, markers),
167167
dependency_mode: options.dependency_mode,
168168
urls: Urls::from_manifest(&manifest, markers)?,
169-
locals: Locals::from_manifest(&manifest, markers)?,
169+
locals: Locals::from_manifest(&manifest, markers),
170170
project: manifest.project,
171171
requirements: manifest.requirements,
172172
constraints: Constraints::from_requirements(manifest.constraints),

crates/uv/tests/pip_install_scenarios.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,7 +1333,7 @@ fn local_simple() {
13331333
filters.push((r"local-simple-", "pkg-"));
13341334

13351335
uv_snapshot!(filters, command(&context)
1336-
.arg("local-simple-a==1.2.3+foo")
1336+
.arg("local-simple-a==1.2.3")
13371337
, @r###"
13381338
success: false
13391339
exit_code: 1
@@ -1344,7 +1344,7 @@ fn local_simple() {
13441344
╰─▶ Because there is no version of albatross==1.2.3 and you require albatross==1.2.3, we can conclude that the requirements are unsatisfiable.
13451345
"###);
13461346

1347-
// The verison '1.2.3+foo' satisfies the constraint '==1.2.3'.
1347+
// The version '1.2.3+foo' satisfies the constraint '==1.2.3'.
13481348
assert_not_installed(&context.venv, "local_simple_a", &context.temp_dir);
13491349
}
13501350

@@ -1386,7 +1386,7 @@ fn local_not_used_with_sdist() {
13861386
+ albatross==1.2.3
13871387
"###);
13881388

1389-
// The verison '1.2.3' with an sdist satisfies the constraint '==1.2.3'.
1389+
// The version '1.2.3' with an sdist satisfies the constraint '==1.2.3'.
13901390
assert_not_installed(
13911391
&context.venv,
13921392
"local_not_used_with_sdist_a",
@@ -1431,7 +1431,7 @@ fn local_used_without_sdist() {
14311431
╰─▶ Because albatross==1.2.3 is unusable because no wheels are available with a matching Python ABI and you require albatross==1.2.3, we can conclude that the requirements are unsatisfiable.
14321432
"###);
14331433

1434-
// The verison '1.2.3+foo' satisfies the constraint '==1.2.3'.
1434+
// The version '1.2.3+foo' satisfies the constraint '==1.2.3'.
14351435
assert_not_installed(
14361436
&context.venv,
14371437
"local_used_without_sdist_a",
@@ -1532,9 +1532,19 @@ fn local_transitive() {
15321532
+ bluebird==2.0.0+foo
15331533
"###);
15341534

1535-
// The verison '2.0.0+foo' satisfies both ==2.0.0 and ==2.0.0+foo.
1536-
assert_not_installed(&context.venv, "local_transitive_a", &context.temp_dir);
1537-
assert_not_installed(&context.venv, "local_transitive_b", &context.temp_dir);
1535+
// The version '2.0.0+foo' satisfies both ==2.0.0 and ==2.0.0+foo.
1536+
assert_installed(
1537+
&context.venv,
1538+
"local_transitive_a",
1539+
"1.0.0",
1540+
&context.temp_dir,
1541+
);
1542+
assert_installed(
1543+
&context.venv,
1544+
"local_transitive_b",
1545+
"2.0.0+foo",
1546+
&context.temp_dir,
1547+
);
15381548
}
15391549

15401550
/// A transitive dependency has both a non-local and local version published, but
@@ -1569,19 +1579,17 @@ fn local_transitive_confounding() {
15691579
uv_snapshot!(filters, command(&context)
15701580
.arg("local-transitive-confounding-a")
15711581
, @r###"
1572-
success: true
1573-
exit_code: 0
1582+
success: false
1583+
exit_code: 1
15741584
----- stdout -----
15751585
15761586
----- stderr -----
1577-
Resolved 2 packages in [TIME]
1578-
Downloaded 2 packages in [TIME]
1579-
Installed 2 packages in [TIME]
1580-
+ albatross==1.0.0
1581-
+ bluebird==2.0.0
1587+
× No solution found when resolving dependencies:
1588+
╰─▶ Because bluebird==2.0.0 is unusable because no wheels are available with a matching Python ABI and albatross==1.0.0 depends on bluebird==2.0.0, we can conclude that albatross==1.0.0 cannot be used.
1589+
And because only albatross==1.0.0 is available and you require albatross, we can conclude that the requirements are unsatisfiable.
15821590
"###);
15831591

1584-
// The verison '1.2.3+foo' satisfies the constraint '==1.2.3'.
1592+
// The version '1.2.3+foo' satisfies the constraint '==1.2.3'.
15851593
assert_not_installed(
15861594
&context.venv,
15871595
"local_transitive_confounding_a",

requirements.in

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
1-
torchvision==0.15.1+cu118
2-
torch==2.0.0+cu118
1+
#torchvision==0.15.1+cu118
2+
#torch==2.0.0+cu118
3+
4+
# This should _fail_. It shouldn't allow a local version.
5+
# torch>2.2.1
6+
7+
# This should return 2.2.0, not a local version.
8+
# torch<2.2.1
9+
10+
torch>=2.2.1

0 commit comments

Comments
 (0)