Avoid erroring when creating `venv` in current working directory (#15537)

## Summary

A strange use-case, but the current behavior is definitely a bug.

Part of https://github.com/astral-sh/uv/issues/15474.
This commit is contained in:
Charlie Marsh 2025-08-26 12:43:29 -04:00 committed by GitHub
parent 2ca8f6d250
commit 0c674619b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 8 deletions

View File

@ -77,6 +77,18 @@ pub(crate) fn create(
base_python.display()
);
// Extract the prompt and compute the absolute path prior to validating the location; otherwise,
// we risk deleting (and recreating) the current working directory, which would cause the `CWD`
// queries to fail.
let prompt = match prompt {
Prompt::CurrentDirectoryName => CWD
.file_name()
.map(|name| name.to_string_lossy().to_string()),
Prompt::Static(value) => Some(value),
Prompt::None => None,
};
let absolute = std::path::absolute(location)?;
// Validate the existing location.
match location.metadata() {
Ok(metadata) if metadata.is_file() => {
@ -172,7 +184,8 @@ pub(crate) fn create(
Err(err) => return Err(Error::Io(err)),
}
let location = std::path::absolute(location)?;
// Use the absolute path for all further operations.
let location = absolute;
let bin_name = if cfg!(unix) {
"bin"
@ -182,13 +195,6 @@ pub(crate) fn create(
unimplemented!("Only Windows and Unix are supported")
};
let scripts = location.join(&interpreter.virtualenv().scripts);
let prompt = match prompt {
Prompt::CurrentDirectoryName => CWD
.file_name()
.map(|name| name.to_string_lossy().to_string()),
Prompt::Static(value) => Some(value),
Prompt::None => None,
};
// Add the CACHEDIR.TAG.
cachedir::ensure_tag(&location)?;

View File

@ -1572,3 +1572,26 @@ fn create_venv_nested_symlink_preservation() -> Result<()> {
Ok(())
}
#[test]
fn create_venv_current_working_directory() {
let context = TestContext::new_with_versions(&["3.12"]);
uv_snapshot!(context.filters(), context.venv()
.arg(".")
.arg("--python")
.arg("3.12"), @r"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Using CPython 3.12.[X] interpreter at: [PYTHON-3.12]
Creating virtual environment at: .
warning: A directory already exists at `.`. In the future, uv will require `--clear` to replace it
Activate with: source bin/activate
"
);
context.root.assert(predicates::path::is_dir());
}