Consolidate logic for checking for a virtual environment (#14214)

We were checking whether a path was an executable in a virtual
environment or the base directory of a virtual environment in multiple
places in the codebase. This PR consolidates this logic into one place.

Closes #13947.
This commit is contained in:
John Mumm 2025-06-23 09:12:43 -04:00 committed by GitHub
parent a9a9e71481
commit 6481aa3e64
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 30 additions and 16 deletions

View file

@ -888,13 +888,8 @@ impl Error {
| InterpreterError::BrokenSymlink(BrokenSymlink { path, .. }) => {
// If the interpreter is from an active, valid virtual environment, we should
// fail because it's broken
if let Some(Ok(true)) = matches!(source, PythonSource::ActiveEnvironment)
.then(|| {
path.parent()
.and_then(Path::parent)
.map(|path| path.join("pyvenv.cfg").try_exists())
})
.flatten()
if matches!(source, PythonSource::ActiveEnvironment)
&& uv_fs::is_virtualenv_executable(path)
{
true
} else {

View file

@ -993,14 +993,9 @@ impl InterpreterInfo {
.symlink_metadata()
.is_ok_and(|metadata| metadata.is_symlink())
{
let venv = executable
.parent()
.and_then(Path::parent)
.map(|path| path.join("pyvenv.cfg").is_file())
.unwrap_or(false);
Error::BrokenSymlink(BrokenSymlink {
path: executable.to_path_buf(),
venv,
venv: uv_fs::is_virtualenv_executable(executable),
})
} else {
Error::NotFound(executable.to_path_buf())

View file

@ -130,14 +130,14 @@ pub(crate) fn virtualenv_from_working_dir() -> Result<Option<PathBuf>, Error> {
for dir in current_dir.ancestors() {
// If we're _within_ a virtualenv, return it.
if dir.join("pyvenv.cfg").is_file() {
if uv_fs::is_virtualenv_base(dir) {
return Ok(Some(dir.to_path_buf()));
}
// Otherwise, search for a `.venv` directory.
let dot_venv = dir.join(".venv");
if dot_venv.is_dir() {
if !dot_venv.join("pyvenv.cfg").is_file() {
if !uv_fs::is_virtualenv_base(&dot_venv) {
return Err(Error::MissingPyVenvCfg(dot_venv));
}
return Ok(Some(dot_venv));