mirror of https://github.com/astral-sh/uv
Include the canonical path in the interpreter query cache key
This commit is contained in:
parent
5fd1bd7dde
commit
469c11ef90
|
|
@ -967,25 +967,10 @@ impl InterpreterInfo {
|
||||||
pub(crate) fn query_cached(executable: &Path, cache: &Cache) -> Result<Self, Error> {
|
pub(crate) fn query_cached(executable: &Path, cache: &Cache) -> Result<Self, Error> {
|
||||||
let absolute = std::path::absolute(executable)?;
|
let absolute = std::path::absolute(executable)?;
|
||||||
|
|
||||||
let cache_entry = cache.entry(
|
// Provide a better error message if the link is broken or the file does not exist. Since
|
||||||
CacheBucket::Interpreter,
|
// `canonicalize_executable` does not resolve the file on Windows, we must re-use this logic
|
||||||
// Shard interpreter metadata by host architecture, operating system, and version, to
|
// for the subsequent metadata read as we may not have actually resolved the path.
|
||||||
// invalidate the cache (e.g.) on OS upgrades.
|
let handle_io_error = |err: io::Error| -> Error {
|
||||||
cache_digest(&(
|
|
||||||
ARCH,
|
|
||||||
sys_info::os_type().unwrap_or_default(),
|
|
||||||
sys_info::os_release().unwrap_or_default(),
|
|
||||||
)),
|
|
||||||
// We use the absolute path for the cache entry to avoid cache collisions for relative
|
|
||||||
// paths. But we don't to query the executable with symbolic links resolved.
|
|
||||||
format!("{}.msgpack", cache_digest(&absolute)),
|
|
||||||
);
|
|
||||||
|
|
||||||
// We check the timestamp of the canonicalized executable to check if an underlying
|
|
||||||
// interpreter has been modified.
|
|
||||||
let modified = canonicalize_executable(&absolute)
|
|
||||||
.and_then(Timestamp::from_path)
|
|
||||||
.map_err(|err| {
|
|
||||||
if err.kind() == io::ErrorKind::NotFound {
|
if err.kind() == io::ErrorKind::NotFound {
|
||||||
// Check if it looks like a venv interpreter where the underlying Python
|
// Check if it looks like a venv interpreter where the underlying Python
|
||||||
// installation was removed.
|
// installation was removed.
|
||||||
|
|
@ -1003,7 +988,31 @@ impl InterpreterInfo {
|
||||||
} else {
|
} else {
|
||||||
err.into()
|
err.into()
|
||||||
}
|
}
|
||||||
})?;
|
};
|
||||||
|
|
||||||
|
let canonical = canonicalize_executable(&absolute).map_err(handle_io_error)?;
|
||||||
|
|
||||||
|
let cache_entry = cache.entry(
|
||||||
|
CacheBucket::Interpreter,
|
||||||
|
// Shard interpreter metadata by host architecture, operating system, and version, to
|
||||||
|
// invalidate the cache (e.g.) on OS upgrades.
|
||||||
|
cache_digest(&(
|
||||||
|
ARCH,
|
||||||
|
sys_info::os_type().unwrap_or_default(),
|
||||||
|
sys_info::os_release().unwrap_or_default(),
|
||||||
|
)),
|
||||||
|
// We use the absolute path for the cache entry to avoid cache collisions for relative
|
||||||
|
// paths. But we don't to query the executable with symbolic links resolved. We include
|
||||||
|
// the canonical path in the cache entry as well, otherwise we can have cache collisions
|
||||||
|
// if an absolute path refers to different interpreters with matching ctimes, e.g., if
|
||||||
|
// you have a `.venv/bin/python` pointing to both Python 3.12 and Python 3.13 that were
|
||||||
|
// modified at the same time.
|
||||||
|
format!("{}.msgpack", cache_digest(&(&absolute, &canonical))),
|
||||||
|
);
|
||||||
|
|
||||||
|
// We check the timestamp of the canonicalized executable to check if an underlying
|
||||||
|
// interpreter has been modified.
|
||||||
|
let modified = Timestamp::from_path(canonical).map_err(handle_io_error)?;
|
||||||
|
|
||||||
// Read from the cache.
|
// Read from the cache.
|
||||||
if cache
|
if cache
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue