mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-01 20:31:12 +00:00
Expand Windows shim detection to include python3.12.exe (#2209)
## Summary Our Windows shim detection wasn't catching shims like `python3.12.exe`. Closes #2208. ## Test Plan Installed Python 3.12 via the Windows Store; verified that `cargo run venv --python 3.12` failed before but passes after this change.
This commit is contained in:
parent
8620b5a52f
commit
cf94df7cb9
1 changed files with 62 additions and 7 deletions
|
|
@ -330,7 +330,7 @@ impl PythonVersionSelector {
|
|||
}
|
||||
|
||||
mod windows {
|
||||
use std::path::PathBuf;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
|
|
@ -412,17 +412,56 @@ mod windows {
|
|||
/// does not want us to do this as the format is unstable. So this is a best effort way.
|
||||
/// we just hope that the reparse point has the python redirector in it, when it's not
|
||||
/// pointing to a valid Python.
|
||||
pub(super) fn is_windows_store_shim(path: &std::path::Path) -> bool {
|
||||
///
|
||||
/// Matches against paths like:
|
||||
/// `C:\Users\crmar\AppData\Local\Microsoft\WindowsApps\python.exe`
|
||||
pub(super) fn is_windows_store_shim(path: &Path) -> bool {
|
||||
// Rye uses a more sophisticated test to identify the windows store shim.
|
||||
// Unfortunately, it only works with the `python.exe` shim but not `python3.exe`.
|
||||
// What we do here is a very naive implementation but probably sufficient for all we need.
|
||||
// There's the risk of false positives but I consider it rare, considering how specific
|
||||
// the path is.
|
||||
// Rye Shim detection: https://github.com/mitsuhiko/rye/blob/78bf4d010d5e2e88ebce1ba636c7acec97fd454d/rye/src/cli/shim.rs#L100-L172
|
||||
path.to_str().map_or(false, |path| {
|
||||
path.ends_with("Local\\Microsoft\\WindowsApps\\python.exe")
|
||||
|| path.ends_with("Local\\Microsoft\\WindowsApps\\python3.exe")
|
||||
})
|
||||
if !path.is_absolute() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut components = path.components().rev();
|
||||
|
||||
// Ex) `python.exe` or `python3.exe` or `python3.12.exe`
|
||||
if !components
|
||||
.next()
|
||||
.and_then(|component| component.as_os_str().to_str())
|
||||
.and_then(|component| component.rsplit_once('.'))
|
||||
.is_some_and(|(name, extension)| name.starts_with("python") && extension == "exe")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ex) `WindowsApps`
|
||||
if !components
|
||||
.next()
|
||||
.is_some_and(|component| component.as_os_str() == "WindowsApps")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ex) `Microsoft`
|
||||
if !components
|
||||
.next()
|
||||
.is_some_and(|component| component.as_os_str() == "Microsoft")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ex) `Local`
|
||||
if !components
|
||||
.next()
|
||||
.is_some_and(|component| component.as_os_str() == "Local")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
@ -464,6 +503,22 @@ mod windows {
|
|||
"###);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn detect_shim() {
|
||||
assert!(super::is_windows_store_shim(
|
||||
r"C:\Users\crmar\AppData\Local\Microsoft\WindowsApps\python.exe".as_ref()
|
||||
));
|
||||
assert!(super::is_windows_store_shim(
|
||||
r"C:\Users\crmar\AppData\Local\Microsoft\WindowsApps\python3.exe".as_ref()
|
||||
));
|
||||
assert!(super::is_windows_store_shim(
|
||||
r"C:\Users\crmar\AppData\Local\Microsoft\WindowsApps\python3.12.exe".as_ref()
|
||||
));
|
||||
assert!(!super::is_windows_store_shim(
|
||||
r"C:\Users\crmar\AppData\Local\Microsoft\WindowsApps\PythonSoftwareFoundation.Python.3.11_qbs5n2kfra8p0\python.exe".as_ref()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue