Add check for using minor version link when creating a venv on Windows (#14252)

There was a regression introduced in #13954 on Windows where creating a
venv behaved as if there was a minor version link even if none existed.
This PR adds a check to fix this.

Closes #14249.
This commit is contained in:
John Mumm 2025-06-25 04:12:32 -04:00 committed by GitHub
parent 5b2c3595a7
commit 177df19f30
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 41 additions and 6 deletions

View file

@ -147,6 +147,7 @@ pub(crate) fn create(
// Create a `.gitignore` file to ignore all files in the venv.
fs::write(location.join(".gitignore"), "*")?;
let mut using_minor_version_link = false;
let executable_target = if upgradeable && interpreter.is_standalone() {
if let Some(minor_version_link) = PythonMinorVersionLink::from_executable(
base_python.as_path(),
@ -167,6 +168,7 @@ pub(crate) fn create(
&minor_version_link.symlink_directory.display(),
&base_python.display()
);
using_minor_version_link = true;
minor_version_link.symlink_executable.clone()
}
} else {
@ -228,7 +230,7 @@ pub(crate) fn create(
// interpreters, this target path includes a minor version junction to enable
// transparent upgrades.
if cfg!(windows) {
if interpreter.is_standalone() {
if using_minor_version_link {
let target = scripts.join(WindowsExecutable::Python.exe(interpreter));
create_link_to_executable(target.as_path(), executable_target.clone())
.map_err(Error::Python)?;

View file

@ -516,7 +516,7 @@ fn create_venv_respects_group_requires_python() -> Result<()> {
name = "foo"
version = "1.0.0"
dependencies = []
[dependency-groups]
dev = ["sortedcontainers"]
other = ["sniffio"]
@ -549,7 +549,7 @@ fn create_venv_respects_group_requires_python() -> Result<()> {
version = "1.0.0"
requires-python = ">=3.11"
dependencies = []
[dependency-groups]
dev = ["sortedcontainers"]
other = ["sniffio"]
@ -582,7 +582,7 @@ fn create_venv_respects_group_requires_python() -> Result<()> {
version = "1.0.0"
requires-python = ">=3.10"
dependencies = []
[dependency-groups]
dev = ["sortedcontainers"]
other = ["sniffio"]
@ -612,7 +612,7 @@ fn create_venv_respects_group_requires_python() -> Result<()> {
name = "foo"
version = "1.0.0"
dependencies = []
[dependency-groups]
dev = ["sortedcontainers"]
@ -643,7 +643,7 @@ fn create_venv_respects_group_requires_python() -> Result<()> {
version = "1.0.0"
requires-python = "<3.12"
dependencies = []
[dependency-groups]
dev = ["sortedcontainers"]
other = ["sniffio"]
@ -1052,6 +1052,39 @@ fn non_empty_dir_exists_allow_existing() -> Result<()> {
Ok(())
}
/// Run `uv venv` followed by `uv venv --allow-existing`.
#[test]
fn create_venv_then_allow_existing() {
let context = TestContext::new_with_versions(&["3.12"]);
// Create a venv
uv_snapshot!(context.filters(), context.venv(), @r"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Using CPython 3.12.[X] interpreter at: [PYTHON-3.12]
Creating virtual environment at: .venv
Activate with: source .venv/[BIN]/activate
"
);
// Create a venv again with `--allow-existing`
uv_snapshot!(context.filters(), context.venv()
.arg("--allow-existing"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Using CPython 3.12.[X] interpreter at: [PYTHON-3.12]
Creating virtual environment at: .venv
Activate with: source .venv/[BIN]/activate
"###
);
}
#[test]
#[cfg(windows)]
fn windows_shims() -> Result<()> {