mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Update packse to pull in additional local version tests (#2462)
Precursor to #2430.
This commit is contained in:
parent
2fb8df3769
commit
17732246df
7 changed files with 587 additions and 34 deletions
|
@ -257,6 +257,19 @@ impl Cache {
|
|||
.write(true)
|
||||
.open(root.join(".git"))?;
|
||||
|
||||
// Add an empty .gitignore to the build bucket, to ensure that the cache's own .gitignore
|
||||
// doesn't interfere with source distribution builds. Build backends (like hatchling) will
|
||||
// traverse upwards to look for .gitignore files.
|
||||
fs::create_dir_all(root.join(CacheBucket::BuiltWheels.to_str()))?;
|
||||
match fs::OpenOptions::new().write(true).create_new(true).open(
|
||||
root.join(CacheBucket::BuiltWheels.to_str())
|
||||
.join(".gitignore"),
|
||||
) {
|
||||
Ok(_) => {}
|
||||
Err(err) if err.kind() == io::ErrorKind::AlreadyExists => (),
|
||||
Err(err) => return Err(err),
|
||||
}
|
||||
|
||||
fs::canonicalize(root)
|
||||
}
|
||||
|
||||
|
|
|
@ -816,7 +816,8 @@ impl<'a, T: BuildContext> SourceDistCachedBuilder<'a, T> {
|
|||
let span =
|
||||
info_span!("download_source_dist", filename = filename, source_dist = %source_dist);
|
||||
let temp_dir =
|
||||
tempfile::tempdir_in(self.build_context.cache().root()).map_err(Error::CacheWrite)?;
|
||||
tempfile::tempdir_in(self.build_context.cache().bucket(CacheBucket::BuiltWheels))
|
||||
.map_err(Error::CacheWrite)?;
|
||||
let reader = response
|
||||
.bytes_stream()
|
||||
.map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))
|
||||
|
@ -896,8 +897,9 @@ impl<'a, T: BuildContext> SourceDistCachedBuilder<'a, T> {
|
|||
} else {
|
||||
debug!("Unpacking for build: {source_dist}");
|
||||
|
||||
let temp_dir = tempfile::tempdir_in(self.build_context.cache().root())
|
||||
.map_err(Error::CacheWrite)?;
|
||||
let temp_dir =
|
||||
tempfile::tempdir_in(self.build_context.cache().bucket(CacheBucket::BuiltWheels))
|
||||
.map_err(Error::CacheWrite)?;
|
||||
|
||||
// Unzip the archive into the temporary directory.
|
||||
let reader = fs_err::tokio::File::open(&path)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! DO NOT EDIT
|
||||
//!
|
||||
//! Generated with ./scripts/scenarios/sync.sh
|
||||
//! Scenarios from <https://github.com/zanieb/packse/tree/0.3.7/scenarios>
|
||||
//! Scenarios from <https://github.com/zanieb/packse/tree/0.3.9/scenarios>
|
||||
//!
|
||||
#![cfg(all(feature = "python", feature = "pypi"))]
|
||||
|
||||
|
@ -27,9 +27,9 @@ fn command(context: &TestContext, python_versions: &[&str]) -> Command {
|
|||
.arg("compile")
|
||||
.arg("requirements.in")
|
||||
.arg("--index-url")
|
||||
.arg("https://astral-sh.github.io/packse/0.3.7/simple-html/")
|
||||
.arg("https://astral-sh.github.io/packse/0.3.9/simple-html/")
|
||||
.arg("--find-links")
|
||||
.arg("https://raw.githubusercontent.com/zanieb/packse/0.3.7/vendor/links.html")
|
||||
.arg("https://raw.githubusercontent.com/zanieb/packse/0.3.9/vendor/links.html")
|
||||
.arg("--cache-dir")
|
||||
.arg(context.cache_dir.path())
|
||||
.env("VIRTUAL_ENV", context.venv.as_os_str())
|
||||
|
@ -66,7 +66,7 @@ fn incompatible_python_compatible_override() -> Result<()> {
|
|||
let context = TestContext::new("3.9");
|
||||
let python_versions = &[];
|
||||
|
||||
// In addition to the standard filters, swap out package names for more realistic messages
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"incompatible-python-compatible-override-", "package-"));
|
||||
|
||||
|
@ -115,7 +115,7 @@ fn compatible_python_incompatible_override() -> Result<()> {
|
|||
let context = TestContext::new("3.11");
|
||||
let python_versions = &[];
|
||||
|
||||
// In addition to the standard filters, swap out package names for more realistic messages
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"compatible-python-incompatible-override-", "package-"));
|
||||
|
||||
|
@ -162,7 +162,7 @@ fn incompatible_python_compatible_override_unavailable_no_wheels() -> Result<()>
|
|||
let context = TestContext::new("3.9");
|
||||
let python_versions = &[];
|
||||
|
||||
// In addition to the standard filters, swap out package names for more realistic messages
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((
|
||||
r"incompatible-python-compatible-override-unavailable-no-wheels-",
|
||||
|
@ -218,7 +218,7 @@ fn incompatible_python_compatible_override_available_no_wheels() -> Result<()> {
|
|||
let context = TestContext::new("3.9");
|
||||
let python_versions = &["3.11"];
|
||||
|
||||
// In addition to the standard filters, swap out package names for more realistic messages
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((
|
||||
r"incompatible-python-compatible-override-available-no-wheels-",
|
||||
|
@ -273,7 +273,7 @@ fn incompatible_python_compatible_override_no_compatible_wheels() -> Result<()>
|
|||
let context = TestContext::new("3.9");
|
||||
let python_versions = &[];
|
||||
|
||||
// In addition to the standard filters, swap out package names for more realistic messages
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((
|
||||
r"incompatible-python-compatible-override-no-compatible-wheels-",
|
||||
|
@ -331,7 +331,7 @@ fn incompatible_python_compatible_override_other_wheel() -> Result<()> {
|
|||
let context = TestContext::new("3.9");
|
||||
let python_versions = &[];
|
||||
|
||||
// In addition to the standard filters, swap out package names for more realistic messages
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((
|
||||
r"incompatible-python-compatible-override-other-wheel-",
|
||||
|
@ -391,7 +391,7 @@ fn python_patch_override_no_patch() -> Result<()> {
|
|||
let context = TestContext::new("3.8.18");
|
||||
let python_versions = &[];
|
||||
|
||||
// In addition to the standard filters, swap out package names for more realistic messages
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"python-patch-override-no-patch-", "package-"));
|
||||
|
||||
|
@ -438,7 +438,7 @@ fn python_patch_override_patch_compatible() -> Result<()> {
|
|||
let context = TestContext::new("3.8.18");
|
||||
let python_versions = &[];
|
||||
|
||||
// In addition to the standard filters, swap out package names for more realistic messages
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"python-patch-override-patch-compatible-", "package-"));
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! DO NOT EDIT
|
||||
//!
|
||||
//! Generated with ./scripts/scenarios/sync.sh
|
||||
//! Scenarios from <https://github.com/zanieb/packse/tree/0.3.7/scenarios>
|
||||
//! Scenarios from <https://github.com/zanieb/packse/tree/0.3.9/scenarios>
|
||||
//!
|
||||
#![cfg(all(feature = "python", feature = "pypi"))]
|
||||
|
||||
|
@ -46,9 +46,9 @@ fn command(context: &TestContext) -> Command {
|
|||
.arg("pip")
|
||||
.arg("install")
|
||||
.arg("--index-url")
|
||||
.arg("https://astral-sh.github.io/packse/0.3.7/simple-html/")
|
||||
.arg("https://astral-sh.github.io/packse/0.3.9/simple-html/")
|
||||
.arg("--find-links")
|
||||
.arg("https://raw.githubusercontent.com/zanieb/packse/0.3.7/vendor/links.html")
|
||||
.arg("https://raw.githubusercontent.com/zanieb/packse/0.3.9/vendor/links.html")
|
||||
.arg("--cache-dir")
|
||||
.arg(context.cache_dir.path())
|
||||
.env("VIRTUAL_ENV", context.venv.as_os_str())
|
||||
|
@ -1289,7 +1289,7 @@ fn local_simple() {
|
|||
╰─▶ Because there is no version of package-a==1.2.3 and you require package-a==1.2.3, we can conclude that the requirements are unsatisfiable.
|
||||
"###);
|
||||
|
||||
// The verison '1.2.3+foo' satisfies the constraint '==1.2.3'.
|
||||
// The version '1.2.3+foo' satisfies the constraint '==1.2.3'.
|
||||
assert_not_installed(&context.venv, "local_simple_a", &context.temp_dir);
|
||||
}
|
||||
|
||||
|
@ -1330,10 +1330,11 @@ fn local_not_used_with_sdist() {
|
|||
+ package-a==1.2.3
|
||||
"###);
|
||||
|
||||
// The verison '1.2.3' with an sdist satisfies the constraint '==1.2.3'.
|
||||
assert_not_installed(
|
||||
// The version '1.2.3' with an sdist satisfies the constraint '==1.2.3'.
|
||||
assert_installed(
|
||||
&context.venv,
|
||||
"local_not_used_with_sdist_a",
|
||||
"1.2.3",
|
||||
&context.temp_dir,
|
||||
);
|
||||
}
|
||||
|
@ -1374,7 +1375,7 @@ fn local_used_without_sdist() {
|
|||
╰─▶ Because package-a==1.2.3 is unusable because no wheels are available with a matching Python ABI and you require package-a==1.2.3, we can conclude that the requirements are unsatisfiable.
|
||||
"###);
|
||||
|
||||
// The verison '1.2.3+foo' satisfies the constraint '==1.2.3'.
|
||||
// The version '1.2.3+foo' satisfies the constraint '==1.2.3'.
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_used_without_sdist_a",
|
||||
|
@ -1470,13 +1471,235 @@ fn local_transitive() {
|
|||
And because you require package-a and you require package-b==2.0.0+foo, we can conclude that the requirements are unsatisfiable.
|
||||
"###);
|
||||
|
||||
// The verison '2.0.0+foo' satisfies both ==2.0.0 and ==2.0.0+foo.
|
||||
// The version '2.0.0+foo' satisfies both ==2.0.0 and ==2.0.0+foo.
|
||||
assert_not_installed(&context.venv, "local_transitive_a", &context.temp_dir);
|
||||
assert_not_installed(&context.venv, "local_transitive_b", &context.temp_dir);
|
||||
}
|
||||
|
||||
/// A transitive constraint on a local version should not match an exclusive ordered
|
||||
/// operator.
|
||||
///
|
||||
/// ```text
|
||||
/// local-transitive-greater-than
|
||||
/// ├── environment
|
||||
/// │ └── python3.8
|
||||
/// ├── root
|
||||
/// │ ├── requires a
|
||||
/// │ │ └── satisfied by a-1.0.0
|
||||
/// │ └── requires b==2.0.0+foo
|
||||
/// │ └── satisfied by b-2.0.0+foo
|
||||
/// ├── a
|
||||
/// │ └── a-1.0.0
|
||||
/// │ └── requires b>2.0.0
|
||||
/// │ └── unsatisfied: no matching version
|
||||
/// └── b
|
||||
/// └── b-2.0.0+foo
|
||||
/// ```
|
||||
#[test]
|
||||
fn local_transitive_greater_than() {
|
||||
let context = TestContext::new("3.8");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"local-transitive-greater-than-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("local-transitive-greater-than-a")
|
||||
.arg("local-transitive-greater-than-b==2.0.0+foo")
|
||||
, @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 2 packages in [TIME]
|
||||
Downloaded 2 packages in [TIME]
|
||||
Installed 2 packages in [TIME]
|
||||
+ package-a==1.0.0
|
||||
+ package-b==2.0.0+foo
|
||||
"###);
|
||||
|
||||
assert_installed(
|
||||
&context.venv,
|
||||
"local_transitive_greater_than_a",
|
||||
"1.0.0",
|
||||
&context.temp_dir,
|
||||
);
|
||||
assert_installed(
|
||||
&context.venv,
|
||||
"local_transitive_greater_than_b",
|
||||
"2.0.0+foo",
|
||||
&context.temp_dir,
|
||||
);
|
||||
}
|
||||
|
||||
/// A transitive constraint on a local version should match an inclusive ordered
|
||||
/// operator.
|
||||
///
|
||||
/// ```text
|
||||
/// local-transitive-greater-than-or-equal
|
||||
/// ├── environment
|
||||
/// │ └── python3.8
|
||||
/// ├── root
|
||||
/// │ ├── requires a
|
||||
/// │ │ └── satisfied by a-1.0.0
|
||||
/// │ └── requires b==2.0.0+foo
|
||||
/// │ └── satisfied by b-2.0.0+foo
|
||||
/// ├── a
|
||||
/// │ └── a-1.0.0
|
||||
/// │ └── requires b>=2.0.0
|
||||
/// │ └── satisfied by b-2.0.0+foo
|
||||
/// └── b
|
||||
/// └── b-2.0.0+foo
|
||||
/// ```
|
||||
#[test]
|
||||
fn local_transitive_greater_than_or_equal() {
|
||||
let context = TestContext::new("3.8");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"local-transitive-greater-than-or-equal-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("local-transitive-greater-than-or-equal-a")
|
||||
.arg("local-transitive-greater-than-or-equal-b==2.0.0+foo")
|
||||
, @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 2 packages in [TIME]
|
||||
Downloaded 2 packages in [TIME]
|
||||
Installed 2 packages in [TIME]
|
||||
+ package-a==1.0.0
|
||||
+ package-b==2.0.0+foo
|
||||
"###);
|
||||
|
||||
// The version '2.0.0+foo' satisfies both >=2.0.0 and ==2.0.0+foo.
|
||||
assert_installed(
|
||||
&context.venv,
|
||||
"local_transitive_greater_than_or_equal_a",
|
||||
"1.0.0",
|
||||
&context.temp_dir,
|
||||
);
|
||||
assert_installed(
|
||||
&context.venv,
|
||||
"local_transitive_greater_than_or_equal_b",
|
||||
"2.0.0+foo",
|
||||
&context.temp_dir,
|
||||
);
|
||||
}
|
||||
|
||||
/// A transitive constraint on a local version should not match an exclusive ordered
|
||||
/// operator.
|
||||
///
|
||||
/// ```text
|
||||
/// local-transitive-less-than
|
||||
/// ├── environment
|
||||
/// │ └── python3.8
|
||||
/// ├── root
|
||||
/// │ ├── requires a
|
||||
/// │ │ └── satisfied by a-1.0.0
|
||||
/// │ └── requires b==2.0.0+foo
|
||||
/// │ └── satisfied by b-2.0.0+foo
|
||||
/// ├── a
|
||||
/// │ └── a-1.0.0
|
||||
/// │ └── requires b<2.0.0
|
||||
/// │ └── unsatisfied: no matching version
|
||||
/// └── b
|
||||
/// └── b-2.0.0+foo
|
||||
/// ```
|
||||
#[test]
|
||||
fn local_transitive_less_than() {
|
||||
let context = TestContext::new("3.8");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"local-transitive-less-than-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("local-transitive-less-than-a")
|
||||
.arg("local-transitive-less-than-b==2.0.0+foo")
|
||||
, @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only package-a==1.0.0 is available and package-a==1.0.0 depends on package-b<2.0.0, we can conclude that all versions of package-a depend on package-b<2.0.0.
|
||||
And because you require package-a and you require package-b==2.0.0+foo, we can conclude that the requirements are unsatisfiable.
|
||||
"###);
|
||||
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_transitive_less_than_a",
|
||||
&context.temp_dir,
|
||||
);
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_transitive_less_than_b",
|
||||
&context.temp_dir,
|
||||
);
|
||||
}
|
||||
|
||||
/// A transitive constraint on a local version should match an inclusive ordered
|
||||
/// operator.
|
||||
///
|
||||
/// ```text
|
||||
/// local-transitive-less-than-or-equal
|
||||
/// ├── environment
|
||||
/// │ └── python3.8
|
||||
/// ├── root
|
||||
/// │ ├── requires a
|
||||
/// │ │ └── satisfied by a-1.0.0
|
||||
/// │ └── requires b==2.0.0+foo
|
||||
/// │ └── satisfied by b-2.0.0+foo
|
||||
/// ├── a
|
||||
/// │ └── a-1.0.0
|
||||
/// │ └── requires b<=2.0.0
|
||||
/// │ └── satisfied by b-2.0.0+foo
|
||||
/// └── b
|
||||
/// └── b-2.0.0+foo
|
||||
/// ```
|
||||
#[test]
|
||||
fn local_transitive_less_than_or_equal() {
|
||||
let context = TestContext::new("3.8");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"local-transitive-less-than-or-equal-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("local-transitive-less-than-or-equal-a")
|
||||
.arg("local-transitive-less-than-or-equal-b==2.0.0+foo")
|
||||
, @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only package-a==1.0.0 is available and package-a==1.0.0 depends on package-b<=2.0.0, we can conclude that all versions of package-a depend on package-b<=2.0.0.
|
||||
And because you require package-a and you require package-b==2.0.0+foo, we can conclude that the requirements are unsatisfiable.
|
||||
"###);
|
||||
|
||||
// The version '2.0.0+foo' satisfies both <=2.0.0 and ==2.0.0+foo.
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_transitive_less_than_or_equal_a",
|
||||
&context.temp_dir,
|
||||
);
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_transitive_less_than_or_equal_b",
|
||||
&context.temp_dir,
|
||||
);
|
||||
}
|
||||
|
||||
/// A transitive dependency has both a non-local and local version published, but
|
||||
/// the non-local version is unuable.
|
||||
/// the non-local version is unusable.
|
||||
///
|
||||
/// ```text
|
||||
/// local-transitive-confounding
|
||||
|
@ -1515,7 +1738,7 @@ fn local_transitive_confounding() {
|
|||
And because only package-a==1.0.0 is available and you require package-a, we can conclude that the requirements are unsatisfiable.
|
||||
"###);
|
||||
|
||||
// The verison '1.2.3+foo' satisfies the constraint '==1.2.3'.
|
||||
// The version '1.2.3+foo' satisfies the constraint '==1.2.3'.
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_transitive_confounding_a",
|
||||
|
@ -1523,6 +1746,286 @@ fn local_transitive_confounding() {
|
|||
);
|
||||
}
|
||||
|
||||
/// A dependency depends on a conflicting local version of a direct dependency.
|
||||
///
|
||||
/// ```text
|
||||
/// local-transitive-conflicting
|
||||
/// ├── environment
|
||||
/// │ └── python3.8
|
||||
/// ├── root
|
||||
/// │ ├── requires a
|
||||
/// │ │ └── satisfied by a-1.0.0
|
||||
/// │ └── requires b==2.0.0+foo
|
||||
/// │ └── satisfied by b-2.0.0+foo
|
||||
/// ├── a
|
||||
/// │ └── a-1.0.0
|
||||
/// │ └── requires b==2.0.0+bar
|
||||
/// │ └── satisfied by b-2.0.0+bar
|
||||
/// └── b
|
||||
/// ├── b-2.0.0+foo
|
||||
/// └── b-2.0.0+bar
|
||||
/// ```
|
||||
#[test]
|
||||
fn local_transitive_conflicting() {
|
||||
let context = TestContext::new("3.8");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"local-transitive-conflicting-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("local-transitive-conflicting-a")
|
||||
.arg("local-transitive-conflicting-b==2.0.0+foo")
|
||||
, @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only package-a==1.0.0 is available and package-a==1.0.0 depends on package-b==2.0.0+bar, we can conclude that all versions of package-a depend on package-b==2.0.0+bar.
|
||||
And because you require package-a and you require package-b==2.0.0+foo, we can conclude that the requirements are unsatisfiable.
|
||||
"###);
|
||||
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_transitive_conflicting_a",
|
||||
&context.temp_dir,
|
||||
);
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_transitive_conflicting_b",
|
||||
&context.temp_dir,
|
||||
);
|
||||
}
|
||||
|
||||
/// A dependency depends on a conflicting local version of a direct dependency, but
|
||||
/// we can backtrack to a compatible version.
|
||||
///
|
||||
/// ```text
|
||||
/// local-transitive-backtrack
|
||||
/// ├── environment
|
||||
/// │ └── python3.8
|
||||
/// ├── root
|
||||
/// │ ├── requires a
|
||||
/// │ │ ├── satisfied by a-1.0.0
|
||||
/// │ │ └── satisfied by a-2.0.0
|
||||
/// │ └── requires b==2.0.0+foo
|
||||
/// │ └── satisfied by b-2.0.0+foo
|
||||
/// ├── a
|
||||
/// │ ├── a-1.0.0
|
||||
/// │ │ └── requires b==2.0.0
|
||||
/// │ │ ├── satisfied by b-2.0.0+foo
|
||||
/// │ │ └── satisfied by b-2.0.0+bar
|
||||
/// │ └── a-2.0.0
|
||||
/// │ └── requires b==2.0.0+bar
|
||||
/// │ └── satisfied by b-2.0.0+bar
|
||||
/// └── b
|
||||
/// ├── b-2.0.0+foo
|
||||
/// └── b-2.0.0+bar
|
||||
/// ```
|
||||
#[test]
|
||||
fn local_transitive_backtrack() {
|
||||
let context = TestContext::new("3.8");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"local-transitive-backtrack-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("local-transitive-backtrack-a")
|
||||
.arg("local-transitive-backtrack-b==2.0.0+foo")
|
||||
, @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only the following versions of package-a are available:
|
||||
package-a==1.0.0
|
||||
package-a==2.0.0
|
||||
and package-a==1.0.0 depends on package-b==2.0.0, we can conclude that package-a<2.0.0 depends on package-b==2.0.0.
|
||||
And because package-a==2.0.0 depends on package-b==2.0.0+bar, we can conclude that all versions of package-a depend on one of:
|
||||
package-b==2.0.0
|
||||
package-b==2.0.0+bar
|
||||
|
||||
And because you require package-a and you require package-b==2.0.0+foo, we can conclude that the requirements are unsatisfiable.
|
||||
"###);
|
||||
|
||||
// Backtracking to '1.0.0' gives us compatible local versions of b.
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_transitive_backtrack_a",
|
||||
&context.temp_dir,
|
||||
);
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_transitive_backtrack_b",
|
||||
&context.temp_dir,
|
||||
);
|
||||
}
|
||||
|
||||
/// A local version should be excluded in exclusive ordered comparisons.
|
||||
///
|
||||
/// ```text
|
||||
/// local-greater-than
|
||||
/// ├── environment
|
||||
/// │ └── python3.8
|
||||
/// ├── root
|
||||
/// │ └── requires a>1.2.3
|
||||
/// │ └── unsatisfied: no matching version
|
||||
/// └── a
|
||||
/// └── a-1.2.3+foo
|
||||
/// ```
|
||||
#[test]
|
||||
fn local_greater_than() {
|
||||
let context = TestContext::new("3.8");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"local-greater-than-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("local-greater-than-a>1.2.3")
|
||||
, @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
Downloaded 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ package-a==1.2.3+foo
|
||||
"###);
|
||||
|
||||
assert_installed(
|
||||
&context.venv,
|
||||
"local_greater_than_a",
|
||||
"1.2.3+foo",
|
||||
&context.temp_dir,
|
||||
);
|
||||
}
|
||||
|
||||
/// A local version should be included in inclusive ordered comparisons.
|
||||
///
|
||||
/// ```text
|
||||
/// local-greater-than-or-equal
|
||||
/// ├── environment
|
||||
/// │ └── python3.8
|
||||
/// ├── root
|
||||
/// │ └── requires a>=1.2.3
|
||||
/// │ └── satisfied by a-1.2.3+foo
|
||||
/// └── a
|
||||
/// └── a-1.2.3+foo
|
||||
/// ```
|
||||
#[test]
|
||||
fn local_greater_than_or_equal() {
|
||||
let context = TestContext::new("3.8");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"local-greater-than-or-equal-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("local-greater-than-or-equal-a>=1.2.3")
|
||||
, @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
Resolved 1 package in [TIME]
|
||||
Downloaded 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ package-a==1.2.3+foo
|
||||
"###);
|
||||
|
||||
// The version '1.2.3+foo' satisfies the constraint '>=1.2.3'.
|
||||
assert_installed(
|
||||
&context.venv,
|
||||
"local_greater_than_or_equal_a",
|
||||
"1.2.3+foo",
|
||||
&context.temp_dir,
|
||||
);
|
||||
}
|
||||
|
||||
/// A local version should be excluded in exclusive ordered comparisons.
|
||||
///
|
||||
/// ```text
|
||||
/// local-less-than
|
||||
/// ├── environment
|
||||
/// │ └── python3.8
|
||||
/// ├── root
|
||||
/// │ └── requires a<1.2.3
|
||||
/// │ └── unsatisfied: no matching version
|
||||
/// └── a
|
||||
/// └── a-1.2.3+foo
|
||||
/// ```
|
||||
#[test]
|
||||
fn local_less_than() {
|
||||
let context = TestContext::new("3.8");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"local-less-than-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("local-less-than-a<1.2.3")
|
||||
, @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only package-a>=1.2.3 is available and you require package-a<1.2.3, we can conclude that the requirements are unsatisfiable.
|
||||
"###);
|
||||
|
||||
assert_not_installed(&context.venv, "local_less_than_a", &context.temp_dir);
|
||||
}
|
||||
|
||||
/// A local version should be included in inclusive ordered comparisons.
|
||||
///
|
||||
/// ```text
|
||||
/// local-less-than-or-equal
|
||||
/// ├── environment
|
||||
/// │ └── python3.8
|
||||
/// ├── root
|
||||
/// │ └── requires a<=1.2.3
|
||||
/// │ └── satisfied by a-1.2.3+foo
|
||||
/// └── a
|
||||
/// └── a-1.2.3+foo
|
||||
/// ```
|
||||
#[test]
|
||||
fn local_less_than_or_equal() {
|
||||
let context = TestContext::new("3.8");
|
||||
|
||||
// In addition to the standard filters, swap out package names for shorter messages
|
||||
let mut filters = INSTA_FILTERS.to_vec();
|
||||
filters.push((r"local-less-than-or-equal-", "package-"));
|
||||
|
||||
uv_snapshot!(filters, command(&context)
|
||||
.arg("local-less-than-or-equal-a<=1.2.3")
|
||||
, @r###"
|
||||
success: false
|
||||
exit_code: 1
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
× No solution found when resolving dependencies:
|
||||
╰─▶ Because only package-a>1.2.3 is available and you require package-a<=1.2.3, we can conclude that the requirements are unsatisfiable.
|
||||
"###);
|
||||
|
||||
// The version '1.2.3+foo' satisfies the constraint '<=1.2.3'.
|
||||
assert_not_installed(
|
||||
&context.venv,
|
||||
"local_less_than_or_equal_a",
|
||||
&context.temp_dir,
|
||||
);
|
||||
}
|
||||
|
||||
/// The user requires any version of package `a` which only has prerelease versions
|
||||
/// available.
|
||||
///
|
||||
|
|
|
@ -137,14 +137,49 @@ def main(scenarios: list[Path], snapshot_update: bool = True):
|
|||
# We do not yet support local version identifiers
|
||||
for scenario in data["scenarios"]:
|
||||
expected = scenario["expected"]
|
||||
if (
|
||||
scenario["name"].startswith("local-")
|
||||
and scenario["name"] != "local-not-latest"
|
||||
if scenario["name"] in (
|
||||
"local-less-than-or-equal",
|
||||
"local-simple",
|
||||
"local-transitive-confounding",
|
||||
"local-transitive-backtrack",
|
||||
"local-used-with-sdist",
|
||||
"local-used-without-sdist",
|
||||
"local-transitive",
|
||||
"local-transitive-less-than-or-equal",
|
||||
):
|
||||
expected["satisfiable"] = False
|
||||
expected[
|
||||
"explanation"
|
||||
] = "We do not have correct behavior for local version identifiers yet"
|
||||
elif scenario["name"] == "local-greater-than":
|
||||
expected["satisfiable"] = True
|
||||
expected["packages"] = [
|
||||
{
|
||||
"name": "local-greater-than-a",
|
||||
"version": "1.2.3+foo",
|
||||
"module_name": "local_greater_than_a",
|
||||
}
|
||||
]
|
||||
expected["explanation"] = (
|
||||
"We do not have correct behavior for local version identifiers yet"
|
||||
)
|
||||
elif scenario["name"] == "local-transitive-greater-than":
|
||||
expected["satisfiable"] = True
|
||||
expected["packages"] = [
|
||||
{
|
||||
"name": "local-transitive-greater-than-a",
|
||||
"version": "1.0.0",
|
||||
"module_name": "local_transitive_greater_than_a",
|
||||
},
|
||||
{
|
||||
"name": "local-transitive-greater-than-b",
|
||||
"version": "2.0.0+foo",
|
||||
"module_name": "local_transitive_greater_than_b",
|
||||
}
|
||||
]
|
||||
expected["explanation"] = (
|
||||
"We do not have correct behavior for local version identifiers yet"
|
||||
)
|
||||
|
||||
# Split scenarios into `install` and `compile` cases
|
||||
install_scenarios = []
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
chevron-blue
|
||||
packse>=0.3.6
|
||||
packse>=0.3.9
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# This file was autogenerated by uv via the following command:
|
||||
# uv pip compile scripts/scenarios/requirements.in -o scripts/scenarios/requirements.txt --refresh-package packse --upgrade
|
||||
# uv pip compile scripts/scenarios/requirements.in -o scripts/scenarios/requirements.txt --refresh-package packse
|
||||
certifi==2024.2.2
|
||||
# via requests
|
||||
charset-normalizer==3.3.2
|
||||
|
@ -14,7 +14,7 @@ hatchling==1.21.1
|
|||
# via packse
|
||||
idna==3.6
|
||||
# via requests
|
||||
importlib-metadata==7.0.1
|
||||
importlib-metadata==7.0.2
|
||||
# via twine
|
||||
jaraco-classes==3.3.1
|
||||
# via keyring
|
||||
|
@ -30,9 +30,9 @@ msgspec==0.18.6
|
|||
# via packse
|
||||
nh3==0.2.15
|
||||
# via readme-renderer
|
||||
packaging==23.2
|
||||
packaging==24.0
|
||||
# via hatchling
|
||||
packse==0.3.7
|
||||
packse==0.3.9
|
||||
pathspec==0.12.1
|
||||
# via hatchling
|
||||
pkginfo==1.10.0
|
||||
|
@ -55,7 +55,7 @@ rfc3986==2.0.0
|
|||
# via twine
|
||||
rich==13.7.1
|
||||
# via twine
|
||||
setuptools==69.1.1
|
||||
setuptools==69.2.0
|
||||
# via packse
|
||||
trove-classifiers==2024.3.3
|
||||
# via hatchling
|
||||
|
@ -65,5 +65,5 @@ urllib3==2.2.1
|
|||
# via
|
||||
# requests
|
||||
# twine
|
||||
zipp==3.17.0
|
||||
zipp==3.18.0
|
||||
# via importlib-metadata
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue