Respect global Python version pins in uv tool run and uv tool install (#14112)
Closes #12921 For `uv tool run`, we'll just use the global Python version for all invocations without an explicit alternative request (i.e., via the `--python` flag). For `uv tool install`, it's a bit more complicated: - If the tool is not installed, we'll use the global Python version - If the tool is already installed, we won't change the Python version unless `--reinstall` or `--python` is used - If the tool was installed with `--python`, we won't use the global Python version, unless the tool is uninstalled first The behavior can be demonstrated as follows ``` $ uv python pin --global 3.12 $ uv tool install flask # uses 3.12 $ uv tool install flask # no-op $ uv python pin --global 3.13 $ uv tool install flask # no-op $ uv tool install flask --reinstall # uses 3.13 $ uv tool install flask -p 3.12 # uses 3.12 $ uv tool install flask # no-op $ uv tool install flask --reinstall # uses 3.12 ``` This is a little more complicated than always reinstalling when the global Python version pin changes, but I think it's probably more intuitive when actually using the tool. We briefly touched on this when adding global version pins at https://github.com/astral-sh/uv/pull/12115#discussion_r1992222278 Minor note: I need to do a self-review of this implementation, as it's a little awkward to encode this behavior in the existing logic.
This commit is contained in:
@@ -46,7 +46,7 @@ use crate::{BrokenSymlink, Interpreter, PythonVersion};
|
||||
/// A request to find a Python installation.
|
||||
///
|
||||
/// See [`PythonRequest::from_str`].
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default, Hash)]
|
||||
#[derive(Debug, Clone, Eq, Default)]
|
||||
pub enum PythonRequest {
|
||||
/// An appropriate default Python installation
|
||||
///
|
||||
@@ -73,6 +73,18 @@ pub enum PythonRequest {
|
||||
Key(PythonDownloadRequest),
|
||||
}
|
||||
|
||||
impl PartialEq for PythonRequest {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.to_canonical_string() == other.to_canonical_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::hash::Hash for PythonRequest {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.to_canonical_string().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> serde::Deserialize<'a> for PythonRequest {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
|
||||
Reference in New Issue
Block a user